Joh*_*ohn 6 javascript xss iframe postmessage
postMessage 可用于在窗口之间发送消息,通常是从 iframe 到父级或从父级到 iframe。
postMessage 仅在一个方向上发送数据并且是外联的 - 不像函数调用,函数调用从调用返回值并内联执行(后者是前者的条件)。
为了将信息发送回“调用者”,“被调用者”必须自己做postMessage。
现在让我们假设我想测试一个合适的监听器是否存在:我会postMessage根据一些约定,如果监听器存在,它会postMessage回来。
在什么时候我可以确定没有听众?我如何实现等待?
我在 IE11、Chrome 和 Firefox 上尝试了以下实验:
postMessage 收到消息后立即回发的 iframe 窗口postMessage 自己的窗口作为在事件处理中调度未来点的一种手段以下是这些步骤的代码:
var iframe = document.getElementById('iframe');
iframe.contentWindow.postMessage('hello', '*');
window.postMessage('schedule', '*')
Run Code Online (Sandbox Code Playgroud)
iframe 的响应代码是这样的:
window.addEventListener('message', function (event) {
window.top.postMessage('echo ' + event.data, '*');
}, false);
Run Code Online (Sandbox Code Playgroud)
父窗口的侦听器本身是这样的:
var n = 0;
window.addEventListener("message", function (event) {
if (n > 4) return;
console.info(event.data);
window.postMessage('(repeat of ' + event.data + ' #' + n + ')', '*')
n++;
}, false);
Run Code Online (Sandbox Code Playgroud)
换句话说,我不断地重新调度事件,以便记录队列的性质。
在 IE11、Chrome 和 Firefox 上,这给出(反复):
schedule <-- shouldn't make the mistake to believe there's no listener yet!
echo hello
(repeat of schedule #0)
(repeat of echo hello #1)
(repeat of (repeat of schedule #0) #2)
Run Code Online (Sandbox Code Playgroud)
我可以“猜测”这是为什么:浏览器有一个消息队列,并将前两条消息(“hello”和“schedule”)放入。它们都将在稍后安排的任何消息之前处理。特别是,iframe 的应答将在处理“hello”消息时被调度,然后将在“schedule”消息之后进行处理。
因此,要确定是否有侦听器,必须在自己的窗口上发布“调度”消息,然后在该事件的处理过程中发布另一条“重复调度 #0”消息。
只有在处理这个间接的“repeat of schedule #0”消息时,仍然没有来自 iframe 的词,我们才能确定没有侦听器。
哇,对于这么简单的问题,这是一个复杂的解决方案。
我的问题是:是否有任何一种保证浏览器有一个公共消息队列,以便真正以这种方式调度事件?
当然,有没有更简单的方法仍然可靠?(甚至不要考虑计时器!)
| 归档时间: |
|
| 查看次数: |
1196 次 |
| 最近记录: |