http网络劫持与DNS劫持原理及预防

现象

运营商、黑客、浏览器厂商、手机厂商,通过某些方式篡改了用户正常访问的网页,插入广告或者其他一些杂七杂八的东西。在一些偏远地区、杂牌运营商尤为常见。

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

  • HTTP劫持 在运营商的路由器节点上,设置协议检测,一旦发现是HTTP请求,而且是html类型请求,则拦截处理。 常见有两种:

    • 类似DNS劫持返回302让用户浏览器跳转到另外的地址。(钓鱼网站就是这么干)
    • 在服务器返回的HTML数据中插入js或dom节点(广告)。(比较常见)

譬如下图:

被劫持怎么办?
  • 对于用户来说,最最直接的就是向运营商投诉。
  • 在html 上加上 <meta http-equiv="Cache-Control" content="no-siteapp"> <meta http-equiv="Cache-Control" content="no-transform " /> 百度官方给的禁止转码声明。
  • 最有用的方式,使用HTTPS ,不让数据那么明显的裸奔。 https 加了SSL协议,会对数据进行加密。
  • 在开发的网页中加入代码过滤,大概思路就是用JavaScript代码检查所有的外链是否属于白名单。

各种劫持的手段都有:
  1. 直接返回一个带广告的HTML
  2. 在原html中插入js,再通过js脚本安插广告;
  3. iframe展示原来正常网页。

js实际对抗
  • 在window 监听 DOMNodeInserted 事件,上报插入的dom、分析插入的dom 信息。(通常匹配所有的url,逐个比较是否白名单域名,如果不是,则判定为劫持,上报的同时,移除dom.parentNode.removeChild(dom)); 刚插入的dom。小心误伤。比较稳的操作是做监测统计,再决策预防。
    ul.addEventListener('DOMNodeInserted',function (e) {
        console.log(e.srcElement)
        console.log(ul.childElementCount)
    })
    ul.addEventListener('DOMNodeRemoved',function (e) {
        console.log(e.srcElement)
        console.log(ul.childElementCount)
    })

复制代码

如下:

    function checkDivHijack(e) {
        var dom = e ? e.srcElement : document.documentElement;
        if (!dom.outerHTML) {
            return;     //e不是一个dom,只是插入一段文本
        }
        var imgList = (dom.nodeName.toUpperCase() == 'IMG') ? [dom] : dom.getElementsByTagName('img');
        if (!imgList || imgList.length == 0) {
            return;
        }
        var httpReg = /^http:\/\/(.*\.qq\.com|.*\.gtimg\.cn|.*\.qlogo\.cn|.*\.qpic\.cn)\//;
        var base64Reg = /^data:image/;
        var src;
        var hijack = false;
        for (var i = 0; i < imgList.length; i++) {
            src = imgList[i].src;
            if (!httpReg.test(src) && !base64Reg.test(src)) {
                hijack = true;
                break;
            }
        }
     }

复制代码

但这样也有漏洞,如果运营商通过div+style设置背景的方式显示广告图,上述代码就无法检查出来。

  • 如果是iframe 插入的情况,比较self 和top是否相同来处理
    function checkIframeHijack() {
        var flag = 'iframe_hijack_redirected';
        if (getURLParam(flag)) {
            sendHijackReport('jiankang.hijack.iframe_ad', 'iframe hijack: ' + location.href);
        } else {
            if (self != top) {
                var url = location.href;
                var parts = url.split('#');
                if (location.search) {
                    parts[0] += '&' + flag + '=1';
                } else {
                    parts[0] += '?' + flag + '=1';
                }
                try {
                    top.location = parts.join('#');
                } catch (e) {
                }
            }
        }
    }
复制代码

eg:

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;
            }
        }
}

复制代码

最终,根本解决办法是使用HTTPS.

如何遍历一个dom 树

function searchDom( node ){
    // 对node 节点处理
    if(node && node.nodeType === 1){
        console.log(node.tagName)
        if(node.tagName === 'IMG'){
            // ...  做白名单判断
        }
    }
    var i = 0, childNodes = node.childNodes, item; 
    for(; i < childNodes.length; i++){
        item = childNodes[i];
        if(item.nodeType === 1){
            // 递归遍历子节点
            searchDom(item)
        }
    }
}

复制代码

参考链接
参考链接
https劫持

3-5年内部岗位(平安、乐信、500万、vivo、oppo)推荐机会,欢迎发简历到: zgxie@126.com

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值