有没有办法阻止 iframe 沙箱发送 postMessages?
Is there a way to prevent an iframe sandbox from sending postMessages?
假设我有一个带有属性 sandbox="allow-scripts"
的 iframe。
我可能会或可能不会控制加载该 iframe 的页面。
除了覆盖父 postMessage 函数之外,是否有任何可能如何防止 iframe 发送 postMessages - 如果父不是我的域,我可能无法做到这一点。
一位同事想出了一个主意。可以总结为:将父域作为域的一部分,以便可以覆盖其 postMessage 方法。
如果无法控制包含 iframe 的顶部 window,为什么不将原始 iframe 放在另一个 iframe 中。额外的框架层可以充当防火墙。通过覆盖该中间防火墙-iframe 的 postMessage-Method,可以确保原始 iframe 可以随心所欲地发布消息,但防火墙-iframe 仅转发希望可发布的传入消息。
当然,这对于 postMessage 调用的目标域必须是什么有一些限制。
您应该只检查 MessageEvent 的只读 source 属性。
<iframe src="evil.html" class="ignore-messages"></iframe>
<iframe src="safe.html"></iframe>
window.addEventListener('message', function(e)
{
// Blacklist messages if e.source matches iframe.ignore-messages
if(Array.from(document.querySelector('iframe.ignore-messages'))
.map(f => f.contentWindow)
.indexOf(e.source) !== -1
) return;
// handle message from safe.html
// this message cannot come from evil.html,
// since that iframe has the class "ignore-messages"
};
实现此目的的其他方法是通过白名单,例如:
// allow only from parent
if(e.source !== parent) return;
// allow only from a given set of iframes
if(Array.from(document.querySelectorAll('iframe.accept-messages')).map(f => f.contentWindow).indexOf(e.source) === -1) return;
白名单相对于黑名单的优势在于,发送消息的 iframe 可能不再在 DOM-树中,或者 classList 可能已更改等。哪个更常见使用 javascript 生成的动态 HTML 时。因此,使用白名单是一种万无一失的方法。
假设我有一个带有属性 sandbox="allow-scripts"
的 iframe。
我可能会或可能不会控制加载该 iframe 的页面。 除了覆盖父 postMessage 函数之外,是否有任何可能如何防止 iframe 发送 postMessages - 如果父不是我的域,我可能无法做到这一点。
一位同事想出了一个主意。可以总结为:将父域作为域的一部分,以便可以覆盖其 postMessage 方法。
如果无法控制包含 iframe 的顶部 window,为什么不将原始 iframe 放在另一个 iframe 中。额外的框架层可以充当防火墙。通过覆盖该中间防火墙-iframe 的 postMessage-Method,可以确保原始 iframe 可以随心所欲地发布消息,但防火墙-iframe 仅转发希望可发布的传入消息。
当然,这对于 postMessage 调用的目标域必须是什么有一些限制。
您应该只检查 MessageEvent 的只读 source 属性。
<iframe src="evil.html" class="ignore-messages"></iframe>
<iframe src="safe.html"></iframe>
window.addEventListener('message', function(e)
{
// Blacklist messages if e.source matches iframe.ignore-messages
if(Array.from(document.querySelector('iframe.ignore-messages'))
.map(f => f.contentWindow)
.indexOf(e.source) !== -1
) return;
// handle message from safe.html
// this message cannot come from evil.html,
// since that iframe has the class "ignore-messages"
};
实现此目的的其他方法是通过白名单,例如:
// allow only from parent
if(e.source !== parent) return;
// allow only from a given set of iframes
if(Array.from(document.querySelectorAll('iframe.accept-messages')).map(f => f.contentWindow).indexOf(e.source) === -1) return;
白名单相对于黑名单的优势在于,发送消息的 iframe 可能不再在 DOM-树中,或者 classList 可能已更改等。哪个更常见使用 javascript 生成的动态 HTML 时。因此,使用白名单是一种万无一失的方法。