我有一个脚本意味着包括第三方网站,创建一个iframe (在我们的起源)。就像这样:
// this script exists on the *host site*
const iframe = document.createElement("iframe");
iframe.src = "https://us.com/iframe";
parent.appendChild(iframe);该脚本公开了一个API,该API通过postMessage与iframe进行内部通信,如下所示:
// This script exists on the *host site*
function getSomeProperty()
{
return new Promise(function (resolve, reject)
{
theIFrame.postMessage("getSomeProperty", "us.com")
window.addEventListener("message", function (event)
{
// ... get the response, making sure its from us.com, etc.
// This is just pseudo code, we don't create a new listener
// on every call in our real code.
resolve(answer);
}
});
}所有这些都很好,我的问题是关于iframe的相应的“消息”侦听器。具体来说,我只想尊重来自创建窗口/原点的请求。换句话说,如果某个独立原点(例如广告)上的并行iframe为我们构造了一个postMessage,我们当然想忽略这一点。我的问题是,仅仅检查发送的window是否为window.parent是否就足够了。
const parent = window.parent;
// This event handler is in the *embedded iframe*
window.addEventListener("message", function (event)
{
// This is being sent from a window other than
// the one that created us, bail!
if (event.window !== parent)
return;
// it is safe to respond...
}据我所知,唯一的方法,这将不是一个充分的检查,如果它是可能的window.parent改变起源,同时保持我们的周围。我可以想象这样的场景:一个iframe可以从一个主机上移除并附加在另一个主机上,但我相信只有当DOM操纵者位于相同的来源(因此可以访问所述DOM)并将我们放置到另一个同样来源的窗口时,这种情况才会发生。
目前,我们采用额外的偏执防御方法,通过查询字符串将原始源传递给iframe,如下所示:
const iframe = document.createElement("iframe");
iframe.src = `https://us.com/iframe?location=${window.location.href}`;从而允许我们检查那个window === window.parent和那个origin === originalOrigin。但是,我们真的很想离开这个模型,因为它必然会中断不同站点之间的缓存(因为每个站点都会由于不同的查询字符串而生成不同的src )。那么,对于我们来说,只检查window === window.parent安全吗?
发布于 2020-01-28 15:08:21
在使用postMessage API时,确保消息来自他们所说的位置的唯一真正安全的方法是使用严格的targetOrigin。这样,您可以确保消息来自您控制的窗口。
您正确地说,这种情况将阻止来自创建消息的窗口以外的传入消息。但是,仍然可以在任何起源上创建带有src="https://us.com/iframe";的src="https://us.com/iframe";。如果它是在恶意页面上创建的呢?这仍然满足这样的条件,即window.parent === parent是true。
https://stackoverflow.com/questions/51460070
复制相似问题