一、概念

1. window.name

  1. 在窗口还没被敞开之前,窗口载入的所有页面都共享同一个window.name。
    这个窗口可了解为chrome的一个tab标签页面,在该页面中跳转关上另一个页面后,这些页面都共享同一个window.name。
  2. 每个页面都能读写window.name。
    这个可能就是平安问题的起源。
  3. 能够存储不超过2M的数据。
    大小没测试过,MDN上没阐明,但有些文章有提到。
可参考:
https://developer.mozilla.org/zh-CN/docs/Web/API/Window/name
https://www.jianshu.com/p/43ff69d076e3

2. postMessage

  1. 能够平安地实现跨源通信。
  2. 提供了一种受控机制来躲避此限度,只有正确的应用,这种办法就很平安。

语法:
otherWindow.postMessage(message, targetOrigin, [transfer]);

事件:
window.addEventListener("message", receiveMessage, false);
message的属性有:data, origin, source

详情可参考:https://developer.mozilla.org/zh-CN/docs/Web/API/Window/postMessage

二、平安问题比拟

简称:
攻击者页面:A
被攻击者页面:B

1. window.name

  1. 可通过在A中嵌入B,实现在A获取B的window.name的数据
  2. 如果B中存在eval执行window.name的代码,则存在xss平安问题,因为在1的根底上,A可批改window.name的数据,从而导致B呈现xss问题

2. demo验证:

验证观点1

A:http://localhost:3000/window.name.html
B:http://localhost:3001/window.name.html
成果如下图:

代码如下:

// A页面:<head>    <meta charset="utf-8">    <title>window.name</title></head><body>    <script>        function iframeOnload() {            var iframe = document.getElementById('iframe');            iframe.onload = function () {                console.log('攻击者页面log:被攻击者页面的数据已拿到:', iframe.contentWindow.name);            }            iframe.src = 'http://localhost:3000/xx.html'        }    </script>    <iframe id="iframe" src="http://localhost:3001/window.name.html" onload="iframeOnload()"></iframe></body>// B页面:<head>    <meta charset="utf-8">    <title>window.name</title></head><body>    <script>        window.name = '这是重要信息!!!'        console.log('被攻击者页面log:', window.name)    </script></body>

验证观点2

A:http://localhost:3000/window.name.html
B:http://localhost:3001/window.name.html
成果如下图:
先关上A页面,1秒钟后,跳转到B页面,并执行alert代码

代码如下:

// A页面<head>    <meta charset="utf-8">    <title>window.name</title></head><body>    <script>        window.name = 'alert(/xss/)'        console.log(window.name)        setTimeout(() => {            location.href = 'http://localhost:3001/window.name.html'        }, 1000)    </script></body>// B页面<head>    <meta charset="utf-8">    <title>window.name</title></head><body>    <script>        console.log('被攻击者页面log:', window.name)        eval(window.name)    </script></body>

3. postMessage

不存在window.name的第一个问题,因为postMessage要指定源targetOrigin,只有不是该源的,都收不到音讯。同时,在接管音讯的时候,也能够指定起源origin,如果起源不对,则可不读取音讯。

解决跨域问题,当初根本用postMessage。

但postMessage也存在有余,比方只能指定特定的源,绝对失常的xhr申请,减少代码量。
所以如果能开cors,则根本是完满的跨域解决方案。

MDN上平安问题的倡议:

如果您不心愿从其余网站接管message,请不要为message事件增加任何事件侦听器。 这是一个齐全十拿九稳的形式来防止平安问题。
如果您的确心愿从其余网站接管message,请始终应用origin和source属性验证发件人的身份。 任何窗口(包含例如http://evil.example.com)都能够向任何其余窗口发送音讯,并且您不能保障未知发件人不会发送歹意音讯。 然而,验证身份后,您依然应该始终验证接管到的音讯的语法。 否则,您信赖只发送受信赖邮件的网站中的安全漏洞可能会在您的网站中关上跨网站脚本破绽。
当您应用postMessage将数据发送到其余窗口时,始终指定准确的指标origin,而不是*。 歹意网站能够在您不知情的状况下更改窗口的地位,因而它能够拦挡应用postMessage发送的数据。