【HTTP劫持和DNS劫持】腾讯的实际业务分析

    简单介绍一下HTTP劫持和DNS劫持的概念,也就是运营商通过某些方式篡改了用户正常访问的网页,插入广告或者其他一些杂七杂八的东西。

首先对运营商的劫持行为做一些分析,他们的目的无非就是赚钱,而赚钱的方式有两种:

    1、对正常网站加入额外的广告,这包括网页内浮层或弹出广告窗口;

    2、针对一些广告联盟或带推广链接的网站,加入推广尾巴。例如普通访问百度首页,被前置跳转为http://www.baidu.com/?tn=90509114_hao_pg

在具体的做法上,一般分为DNS劫持和HTTP劫持。

DNS劫持:

    一般而言,用户上网的DNS服务器都是运营商分配的,所以,在这个节点上,运营商可以为所欲为。

    例如,访问http://jiankang.qq.com/index.html,正常DNS应该返回腾讯的ip,而DNS劫持后,会返回一个运营商的中间服务器ip。访问该服务器会一致性的返回302,让用户浏览器跳转到预处理好的带广告的网页,在该网页中再通过iframe打开用户原来访问的地址。

HTTP劫持:

    在运营商的路由器节点上,设置协议检测,一旦发现是HTTP请求,而且是html类型请求,则拦截处理。后续做法往往分为2种,1种是类似DNS劫持返回302让用户浏览器跳转到另外的地址,还有1种是在服务器返回的HTML数据中插入js或dom节点(广告)。

 在用户角度,这些劫持的表现分为:

    1、网址被无辜跳转,多了推广尾巴;

    2、页面出现额外的广告(iframe模式或者直接同页面插入了dom节点)。

 处理办法:

    1、先对外网做检测,上报被劫持的情况。

            对于我这个业务而言,加推广尾巴没意义,那么就剩下植入广告的问题了。页面广告可能通过iframe方式,也可以通过dom节点方式,需要在首页检查这两种情况。

window.addEventListener('DOMNodeInserted', checkDivHijack);    
function checkDivHijack(e) {
        var html = e ? (e.srcElement.outerHTML || e.srcElement.wholeText) : $('html').html();
        var reg = /http:\/\/([^\/]+)\//g;
        var urlList = html.match(reg);
        if (!urlList || urlList.length == 0) {
            return;
        }
        reg = /^http:\/\/(.*\.qq\.com|.*\.gtimg\.cn|.*\.qlogo\.cn|.*\.qpic\.cn|.*\.wanggou\.com)\/$/;
        var hijack = false;
        for (var i = 0; i < urlList.length; i++) {
            if (!reg.test(urlList[i])) {
                hijack = true;
                break;
            }
        }
}

 (注:事后发现这个url检查不够严谨,虽然劫持的情况都能发现,但也把产品原有的一些正常插入做劫持误报了。例如<a href="http://jiankang.qq.com" data-id="1">,不过这个是小细节,把正则表达式完善一下就ok了)

    2、针对被iframe加载的情况,需要先找到运营商设置的劫持规律。

            在iframe中的网页能正常打开,而不是又被拦截加iframe,可能是因为请求的url上或cookie上运营商做了标记。我们可以利用这个规则,躲过劫持。

    3、针对注入dom节点的情况,初始化时做检查,而且后续dom注入也做检查。可以检查dom中是否含有白名单以外的http链接,如果有,就可以判定为http劫持。

    4、在前端以外的处理办法还有

        a) 终端拦截所有返回包,判断ip来自黑名单(劫持的中间ip)则丢弃返回包。

                这种做法的原因是,运营商劫持http请求后,并不是完全丢弃请求包,而是做了复制,一份继续发给目标服务器,另外一份做劫持处理直接返回302。因为这个302会比目标服务器的正常返回早得多,所以用户浏览器会只认第一个302,而丢弃后到的正常返回。

                如果先把第一个302丢弃,等待后续正常返回,则问题解决。

        b) 终端拦截请求包,并拆包发送。

                运营商一般判断是否劫持,通过判断是否HTTP请求。 一般只会检测TCP连接建立后的第一个数据包,如果其是一个完整的HTTP协议才会被标记;如果并非是一个完整的HTTP协议,由于无法得到足够多的劫持信息,所以并不会被标记为HTTP协议。 

                所以,只要把请求包切得足够细,就能躲过一部分劫持(如果运营商学习“墙”大力气做多包拦截就没辙了)。

    5、当然,最终,根本解决办法是使用HTTPS,不过这个涉及到很多业务的修改,成本较高。如果劫持比例小,也许通过适当的补救做法会更好。

来看看检测到的劫持情况:

总体1500万pv的业务,一天竟然有100万的劫持上报,即使排除一半的误报,也代表说20个用户中,就接近有1个用户出现被劫持的情况。

可见,各种小运营商(尤其是移动)的心是有多黑!胆子是有多大!

各种劫持的手段都有:

  1、直接返回一个带广告的HTML;

  2、在原html中插入js,再通过js脚本安插广告;

  3、iframe展示原来正常网页。

各种丑恶的嘴脸都被记录在案:

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏Java技术栈

8条关于Web前端性能的优化建议

一般网站优化都是优化后台,如接口的响应时间、SQL优化、后台代码性能优化、服务器优化等。高并发情况下,对前端web优化也是非常重要的。 下面说说几种常见的优化措...

3345
来自专栏Java3y

Servlet第六篇【Session介绍、API、生命周期、应用、与Cookie区别】

什么是Session Session 是另一种记录浏览器状态的机制。不同的是Cookie保存在浏览器中,Session保存在服务器中。用户使用浏览器访问服务器的...

4435
来自专栏DOTNET

asp.net web api 下载之断点续传

一、基本思想 利用 HTTP 请求的Range标头值,来向服务端传递请求数据的开始位置和结束位置。服务端获得这两个参数后,将指定范围内的数据传递给客户端。当客户...

43912
来自专栏SDNLAB

源码解读ODL与OpenFlow交换机建立过程

编者按:OpenDaylight两大技术特色:1.采用了OSGi框架;2.引入了SAL,而今天我们主要介绍服务抽象层(SAL)适配的南向协议之一OF协议模块。 ...

3294
来自专栏Web项目聚集地

RESTful 接口实现简明指南

在我所见过的 RESTful 接口的实现中,以 GitHub 最让人惊叹。我第一次如此强烈得感受到 REST 接口的美妙,完全满足了我所期待的「接口的形式美感」...

581
来自专栏张善友的专栏

HTTP Basic Authentication验证WCF Data Service

WCF Data Service是OData协议,也是RESTFul Service的一种,上篇文章已经介绍了HTTP Basic Authentication...

1908
来自专栏小狼的世界

Python 网络请求模块 urllib 、requests

Python 给人的印象是抓取网页非常方便,提供这种生产力的,主要依靠的就是 urllib、requests这两个模块。

632
来自专栏短信防刷

腾讯云短信图片验证码防刷接入指引

开发者采用腾讯云短信做短信注册登陆验证码时,注册登陆页面暴露在外网给用户使用。恶意分子会利用从网站上找到的短信发送 URL ,发送 HTTP 请求,每次请求给用...

5568
来自专栏Python爬虫实战

Python爬虫利器:Requests库的使用

写了一些爬虫,从urllib库转到requests库,到目前为止,个人感觉requests库是最简单易用的HTTP库,以下这段话来自requests官网:

511
来自专栏前端之路

封装localStorage本地数据存取方法

1183

扫码关注云+社区