关闭

JavaScript防流量劫持【前端安全】

时间: 2019-02-15阅读: 1249标签: 安全

劫持产生的原因和方式

在网页开发的访问过程中,http是我们主要的访问协议。我们知道http是一种无状态的连接。即没有验证通讯双方的身份,也没有验证信息的完整性,所以很容易受到篡改。运营商就是利用了这一点篡改了用户正常访问的网页,插入广告或者其他一些杂七杂八的东西,达到盈利的目的。

运营商的一般做法有以下手段:

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

2、针对一些广告联盟或带推广链接的网站,加入推广尾巴;

3、把我们的站点非法解析到其他的站点,比如我们在浏览器输入http://baidu.com,百度绑定的服务器ip地址是111.13.101.208,此时如果运营商的dns服务器将baidu.com的对应的ip地址改为qq的服务器ip 14.17.32.211,我们输入http://baidu.com就会跳转到QQ的页面。

以上的手段,通过原理归纳为两种


1、HTTP劫持

当我们使用HTTP请求请求一个网站页面的时候,网络运营商会在正常的数据流中插入精心设计的网络数据报文,让客户端(通常是浏览器)展示“错误”的数据,通常是一些弹窗,宣传性广告或者直接显示某网站的内容,大家应该都有遇到过。做法1、2就是通过这种方式


2、DNS劫持

我们通过域名访问网页的时候,都需要通过DNS服务器把域名解析到对应的服务器地址上,而用户上网的DNS服务器都是运营商分配的。所以,在这个节点上,运营商可以为所欲为。做法3就是通过这种方式

对于以上的劫持方式,我们作为前端的开发人员,通过JavaScript如何来做到有效的防护呢?

对于DNS劫持,由于发生在域名解析的时候,我们无法控制,JavaScript更无能为力。我们能做的就是拿起手机,投诉网络运营商,或者直接打工信部电话(12300)投诉。


http劫持防范

对于http劫持,运营商在实现上一般有以下几种做法

1、iframe嵌套展示原来正常网页
2、在原html中插入js,再通过js脚本安插广告
3、直接返回一个带广告的html

首先我们来看页面被嵌入了 iframe 的情况。网络运营商为了尽可能地减少植入广告对原有网站页面的影响,通常会通过把原有网站页面放置到一个和原页面相同大小的 iframe 里面去,那么就可以通过这个 iframe 来隔离广告代码对原有页面的影响。这种情况比较容易处理。我们只要判断我们的页面是否被嵌套在iframe中即可。Window对象中有两个属性self(指向本身的窗口),top(指向顶层的窗口)可以帮我们来识别判断

我们可以这样简单判断:

if (window.self != window.top) {
  var url = location.href;
    top.location = url;
}

但是,有时候我们在实际业务中,我们的页面确实需要被嵌套在iframe中推广,上面的判断会导致页面无法嵌套,这时候我们可以采用配置域名白名单的方式来解决

var avoidIframeNest = {
    whiteList : [],
    init: function(whiteList){
        if(Object.prototype.toString.call(whiteList) == "[object Array]"){
            this.whiteList = whiteList;
        }
        this.redirect();
    },
    redirect: function(){
        if(self != top){
            var parentUrl = document.referrer;
            //是否在白名单内
            for(var i = 0 ,length = this.whiteList.length ; i < length ; ++ i){
                var reg = new RegExp(this.whiteList[i],'i');

                if(reg.test(parentUrl)){
                  return;
                }
            }
            //页面跳转
            var url = location.href;
            top.location = url;
        }
    }
}


通过配置白名单的方式,比较适合于我们经常用到的域名,通常我们会遇到这样的需求,合作方要求嵌套我们的页面,我们如果将合作方也加入到我们白名单,一方面会导致白名单很长,另一方面我们需要手动去改代码,这样很不方便。这种情况,我们可以在嵌套的url上加上域名的参数判断,要求嵌套页面带上域名参数,如果匹配,就认为合法。

var avoidIframeNest = {
    whiteList : [],
    init: function(whiteList){
        if(Object.prototype.toString.call(whiteList) == "[object Array]"){
            this.whiteList = whiteList;
        }
        this.redirect();
    },
    redirect: function(){
        if(self != top){
            var parentUrl = document.referrer;
            //是否在白名单内
            for(var i = 0 ,length = this.whiteList.length ; i < length ; ++ i){
                var reg = new RegExp(this.whiteList[i],'i');

                if(reg.test(parentUrl)){
                  return;
                }
            }

            //判断URL是否带指定参数
            var iframeDomain = this.getUrlParam('iframe_domain');
            if(iframeDomain && parentUrl.indexOf(iframeDomain) != -1){
                return;
            }
            //页面跳转
            var url = location.href;
            top.location = url;
        }
    },
    getUrlParam : function(key) {
        var regStr = "^.*[\\?|\\&]" + key + "\\=([^\\&]*)",
            url = location.href;
        reg = new RegExp(regStr,'i');;
        var ret = url.match(reg);
        if (ret != null) {
            return decodeURIComponent(ret[1]);
        } else {
            return "";
        }
    }
}

avoidIframeNest.init(['baidu.com']);


通过上述的方法,基本可以解决iframe嵌套问题

对于js注入问题,一般都会在页面中插入图片标签,展示广告,诱导用户点击。针对这种方式,我们可以通过监控页面插入的图片内容来检测。这里,我们可以利用HTML5的新特性MutationObserver 和window下的DOMNodeInserted事件

Mutation Observer(变动观察器)是监视DOM变动的接口。当DOM对象树发生任何变动时,Mutation Observer会得到通知。具体的介绍可以参考:  

可以监听某个 DOM 范围内的结构变化

DOMNodeInserted顾名思义,可以监听某个 DOM 范围内的结构变化,这个特性只有在firefox的低版本和webkit中使用,IE不支持,这里我们可以作为低版本浏览器的兼容实现。

var validInsertImg = {
    httpReg : /^http:\/\/(.*\.baidu\.com|.*\.netwin\.com)\//,
    //验证非法图片
    validIllegalityImg : function(src){
        var httpReg = this.httpReg;
        return !httpReg.test(src);
    },
    init : function(){
        this.monitor();
    },
    monitor: function(){
        var MutationObserver = window.MutationObserver ||
        window.WebKitMutationObserver || 
        window.MozMutationObserver;
        var mutationObserverSupport = !!MutationObserver;
        //html5监控变化属性
        if(!mutationObserverSupport){
            this.mutationListen(MutationObserver);
        }else{
            this.insertedListen();
        }
    },
    insertedListen : function(){
        var that = this;
        document.addEventListener('DOMNodeInserted', function(e) {
            var dom = e ? e.srcElement : document.documentElement;
            if (!dom.outerHTML) {
                return;
            }
            var imgList = (dom.nodeName.toUpperCase() == 'IMG') ? [dom] : dom.getElementsByTagName('img');
            if (!imgList || imgList.length == 0) {
                return;
            }
             for (var i = 0; i < imgList.length; i++) {
                   that.removeNode(imgList[i]);
            }
        });
    },
    mutationListen: function(MutationObserver){
        var that = this;
        var observer = new MutationObserver(function(mutations){
            mutations.forEach(function(mutation){
                var nodes = mutation.addedNodes;
                for(var i = 0 ; i < nodes.length ; i++){
                    var node = nodes[i];
                    that.removeNode(node);
                }
            })
        })
        observer.observe(document, {
          subtree: true,
          childList: true
        });

    },

    //删除node
    removeNode : function(node){
        if(node.nodeName.toUpperCase() == 'IMG'){
            var src = node.src;
            if(this.validIllegalityImg(src)){
                node.parentNode.removeChild(node);
                  console.log('拦截可疑静态脚本:', node.src);
            }
        }
    }
}

validInsertImg.init();

body = document.getElementsByTagName('body')[0];
 var img = document.createElement('img');
     img.setAttribute('src','http://m.baidu.com/img/b')
      body.appendChild(img);

 var img1 = document.createElement('img');
     img1.setAttribute('src','/YTRYTRY/A.PNG')
    body.appendChild(img1);


对于在返回html内容中插入广告,我们可以借鉴注入的方式,进入页面就检测的img图片路径是否在白名单内

以上方法,都是针对运营商劫持的常用手段进行的一些黑科技操作。只能尽量的减少劫持给我们带来的负面影响。针对劫持问题,最好的办法就是全站升级https的方式,验证通讯双方的身份以及信息的安全性。

但是https也不能完全的解决劫持问题,如果https页面被劫持,浏览器会出现空白页面或者提示不安全,无法显示正常的内容。这也会影响到用户的体验。但是还是推荐使用https,如果大部分的网站都使用了https,运营商的劫持无法达到目的,自然不会去做这样吃力不讨好的事情。


站长推荐

1.云服务推荐: 国内主流云服务商,各类云产品的最新活动,优惠券领取。地址:阿里云腾讯云华为云

2.广告联盟: 整理了目前主流的广告联盟平台,如果你有流量,可以作为参考选择适合你的平台点击进入

链接: http://www.fly63.com/article/detial/2027

关闭

利用CSS注入(无iFrames)窃取CSRF令牌

要做到无iFrame,我将使用一种类似于之前我讨论过的方法:我将创建一个弹窗,然后在设置计时器后更改弹出窗口的位置。使用这种方法,我仍然可以加载受害者的CSS,但我不再依赖于受害者是否允许iFrame。

常见Web安全问题攻防解析

XSS (Cross Site Script),跨站脚本攻击,因缩写和 CSS (Cascading Style Sheets) 重叠,所以叫 XSS。XSS 的原理是恶意攻击者往 Web 页面里插入恶意可执行网页脚本代码,当用户浏览该页之时,嵌入其中 Web 里面的脚本代码会被执行

14个Linux系统安全小妙招

对于互联网IT从业人员来说,越来越多的工作会逐渐转移到Linux系统之上,这一点,无论是开发、运维、测试都应该是深有体会。曾有技术调查网站W3Techs于2018年11月就发布一个调查报告,报告显示Linux在网站服务器的系统中使用率高达37.2%

如何构建网络安全策略?

组织面临着对其信息系统和数据的诸多威胁。了解网络安全的所有基本要素是攻克这些威胁的第一步。网络安全是确保信息的完整性、保密性和可用性(ICA)的实践

Js混淆安全加固

在安全攻防战场中,前端代码都是公开的,那么对前端进行加密有意义吗?可能大部分人的回答是,毫无意义,不要自创加密算法,直接用HTTPS吧。但事实上,即使不了解密码学,也应知道是有意义的,因为加密前和解密后的环节

利用HTML5标签进行DDoS攻击的新方法揭秘

在此次攻击活动中,DDoS攻击请求峰值达到了7500次请求/秒,在大概4个小时内攻击者总共利用了4000多个不同的用户向攻击目标发送了超过7000万次恶意请求。Imperva的研究人员在其发布的安全分析报告中指出

第三方 CSS 并不安全

第三方内容在其沙箱区域内具有强大的能力。如果你担心恶意用户诱使你的网站加载第三方资源,可以通过 CSP 用作防护手段,其可以限制加载图片,脚本和样式的来源。

js安全问题:不安全的JS

在某些特别的场景下,我们需要编译执行外部输入的JS代码。在浏览器端,我们可以借助new Function 、eval等API。而在 node 端,我们可以借助vm模块实现一个沙箱,运行外部输入的JS 代码。但无论是浏览器端,还是node端

Web安全:你必须知道的“Cookie安全”

http是无状态的请求响应。每次的请求响应之后,连接会立即断开或延时断开(保持一定的连接有效期)。断开后,下一次请求再重新建立。在http连接时,通过cookie进行会话跟踪,第一次响应时设置的Cookie在随后的每次请求中都会发送出去

浅谈前端安全

将Web安全问题按照发生的区域来分类,发生在浏览器、Web页面中的安全问题就是前端安全问题。同源:URL由协议、域名、端口和路径组成,如果两个URL的协议、域名和端口相同,则表示他们同源。

点击更多...

内容以共享、参考、研究为目的,不存在任何商业目的。其版权属原作者所有,如有侵权或违规,请与小编联系!情况属实本人将予以删除!