用postMessage检查window.parent的原始点吗?

时间:2018-07-21 20:59:20

标签: javascript iframe cross-domain same-origin-policy postmessage

我有一个脚本,打算由第三方网站包括一个创建iframe(基于我们的网站)的脚本。像这样:

<video width="320" height="240" controls autoplay>

该脚本公开了一个API,该API通过// this script exists on the *host site* const iframe = document.createElement("iframe"); iframe.src = "https://us.com/iframe"; parent.appendChild(iframe); 与iframe内部进行通信,例如:

postMessage

这一切都很好,我的问题是关于iframe的相应“消息”侦听器的。具体来说,我想尊重创建窗口/来源中的请求。换句话说,如果某个平行的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); } }); } ,我们当然想忽略它。我的问题是仅检查发送的postMessage是否为window是否足够?

window.parent

据我了解, 不是足够的检查的唯一方法是window.parent是否有可能更改原点,同时保持我们周围。我可以想象这样一种场景:可以将iframe从一台主机上删除并将appendChild'ed到另一台主机上,但是我相信只有在DOM机械手位于同一来源(从而可以访问所述DOM)并将我们放入另一个起源相同的窗口。

当前,我们采用了额外的偏执狂防御措施,例如通过查询字符串将原始起点传递给iframe:

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...
}

因此,我们可以检查const iframe = document.createElement("iframe"); iframe.src = `https://us.com/iframe?location=${window.location.href}`; window === window.parent。但是,我们真的想脱离此模型,因为它必然会中断跨不同站点的缓存(由于每个查询字符串不同,每个站点都会生成不同的src URL)。因此,对我们来说,仅检查origin === originalOrigin是否安全?

1 个答案:

答案 0 :(得分:1)

使用postMessage API时,确保消息来自他们所说的地方的唯一真正安全的方法是使用严格的targetOrigin。这样,您可以确保邮件来自您控制的窗口。

您说的很对,这种情况会阻止传入的消息,而不是来自创建消息的窗口的消息。但是,仍可以在任何来源上创建带有src="https://us.com/iframe";的iFrame。如果它是在恶意页面上创建的,该怎么办?这仍将满足window.parent === parenttrue的条件。