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

    简单介绍一下HTTP劫持和DNS劫持的概念,也就是运营商经过某些方式篡改了用户正常访问的网页,插入广告或者其余一些杂七杂八的东西。
 
    首先对运营商的劫持行为作一些分析,他们的目的无非就是赚钱,而赚钱的方式有两种:
    一、对正常网站加入额外的广告,这包括网页内浮层或弹出广告窗口;
    二、针对一些广告联盟或带推广连接的网站,加入推广尾巴。例如普通访问百度首页,被前置跳转为 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节点(广告)。
 
 
     在用户角度,这些劫持的表现分为:
    一、网址被无辜跳转,多了推广尾巴;
    二、页面出现额外的广告(iframe模式或者直接同页面插入了dom节点)。
 
 
     处理办法:
    一、先对外网作检测,上报被劫持的状况。
            对于我这个业务而言,加推广尾巴没意义,那么就剩下植入广告的问题了。页面广告可能经过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了)html

 
    二、针对被iframe加载的状况,须要先找到运营商设置的劫持规律。
            在iframe中的网页能正常打开,而不是又被拦截加iframe,多是由于请求的url上或cookie上运营商作了标记。咱们能够利用这个规则,躲过劫持。
 
    三、针对注入dom节点的状况,初始化时作检查,并且后续dom注入也作检查。能够检查dom中是否含有白名单之外的http连接,若是有,就能够断定为http劫持。
 
    四、在前端之外的处理办法还有
        a) 终端拦截全部返回包,判断ip来自黑名单(劫持的中间ip)则丢弃返回包。
                这种作法的缘由是,运营商劫持http请求后,并非彻底丢弃请求包,而是作了复制,一份继续发给目标服务器,另一份作劫持处理直接返回302。由于这个302会比目标服务器的正常返回早得多,因此用户浏览器会只认第一个302,而丢弃后到的正常返回。
                若是先把第一个302丢弃,等待后续正常返回,则问题解决。
        b) 终端拦截请求包,并拆包发送。
                运营商通常判断是否劫持,经过判断是否HTTP请求。 通常只会检测TCP链接创建后的第一个数据包,若是其是一个完整的HTTP协议才会被标记;若是并不是是一个完整的HTTP协议,因为没法获得足够多的劫持信息,因此并不会被标记为HTTP协议。 
                因此,只要把请求包切得足够细,就能躲过一部分劫持(若是运营商学习“墙”大力气作多包拦截就没辙了)。
        
    五、固然,最终,根本解决办法是使用HTTPS,不过这个涉及到不少业务的修改,成本较高。若是劫持比例小,也许经过适当的补救作法会更好。
 
 
   来看看检测到的劫持状况:
整体1500万pv的业务,一天居然有100万的劫持上报,即便排除一半的误报,也表明说20个用户中,就接近有1个用户出现被劫持的状况。
可见,各类小运营商(尤为是移动)的心是有多黑!胆子是有多大!
 
   各类劫持的手段都有:
  一、直接返回一个带广告的HTML;
  二、在原html中插入js,再经过js脚本安插广告;
  三、iframe展现原来正常网页。
 
   各类丑恶的嘴脸都被记录在案:
  
  
  
相关文章
相关标签/搜索