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

在运营商的路由器节点上,设置协议检测,一旦发现是HTTP请求,而且是html类型请求,则拦截处理 。后续做法往往分为2种,1种是类似DNS劫持返回302让用户浏览器跳转到另外的地址,还有1种是在服务器返回的HTML数据中插入js或dom节点(广告) 。
在用户角度,这些劫持的表现分为:
1、网址被无辜跳转,多了推广尾巴;
2、页面出现额外的广告(模式或者直接同页面插入了dom节点) 。
处理办法:
1、先对外网做检测,上报被劫持的情况 。
对于我这个业务而言,加推广尾巴没意义,那么就剩下植入广告的问题了 。页面广告可能通过方式,也可以通过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检查不够严谨,虽然劫持的情况都能发现,但也把产品原有的一些正常插入做劫持误报了 。例如,不过这个是小细节,把正则表达式完善一下就ok了)

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

文章插图
2、针对被加载的情况,需要先找到运营商设置的劫持规律 。
在中的网页能正常打开,而不是又被拦截加,可能是因为请求的url上或上运营商做了标记 。我们可以利用这个规则,躲过劫持 。
3、针对注入dom节点的情况,初始化时做检查,而且后续dom注入也做检查 。可以检查dom中是否含有白名单以外的http链接,如果有,就可以判定为http劫持 。
4、在前端以外的处理办法还有
a) 终端拦截所有返回包,判断ip来自黑名单(劫持的中间ip)则丢弃返回包 。
这种做法的原因是,运营商劫持http请求后,并不是完全丢弃请求包,而是做了复制,一份继续发给目标服务器,另外一份做劫持处理直接返回302 。因为这个302会比目标服务器的正常返回早得多,所以用户浏览器会只认第一个302,而丢弃后到的正常返回 。
如果先把第一个302丢弃,等待后续正常返回,则问题解决 。
b) 终端拦截请求包,并拆包发送 。
运营商一般判断是否劫持,通过判断是否HTTP请求 。一般只会检测TCP连接建立后的第一个数据包,如果其是一个完整的HTTP协议才会被标记;如果并非是一个完整的HTTP协议,由于无法得到足够多的劫持信息,所以并不会被标记为HTTP协议 。
所以,只要把请求包切得足够细,就能躲过一部分劫持(如果运营商学习“墙”大力气做多包拦截就没辙了) 。
5、当然,最终,根本解决办法是使用HTTPS,不过这个涉及到很多业务的修改,成本较高 。如果劫持比例小,也许通过适当的补救做法会更好 。
【HTTP劫持和DNS劫持】腾讯的实际业务分析

文章插图
来看看检测到的劫持情况:
【HTTP劫持和DNS劫持】腾讯的实际业务分析

文章插图
总体1500万pv的业务,一天竟然有100万的劫持上报,即使排除一半的误报,也代表说20个用户中,就接近有1个用户出现被劫持的情况 。
可见,各种小运营商(尤其是移动)的心是有多黑!胆子是有多大!
各种劫持的手段都有:
1、直接返回一个带广告的HTML;