安全使用window.postMessage,是“if(event.source!== window){return;}”好吗?

时间:2013-12-11 17:46:20

标签: javascript security message-queue postmessage

我想使用window.addEventListener("message",myOnmessageCallback,false)来接收来自我window本身的邮件。 (这就是说我不想让myOnmessageCallback函数容易接收来自其他来源的恶意消息(我认为可能是其他帧,browserWindows,制表符,父和iframe,右?)。

因此,我想,如果这避免触及任何来自window本身的东西。

function myOnmessageCallback(event)
{
  if(event.orign !== window)
  {
  // I assume the message is from not this window here, therefore ignore it.
  return;
  }

  //do some useful stuff with the message received (only from window)
}

这似乎是一种减少myOnmessageCallback回调的好方法 邮件是通过网页本身window.postMessage()发送的吗?

PS:对于那些认为我希望减少postMessage onmessage能力的人。我希望有一种方法可以在Javascript执行队列中放置一些内容,允许在两者之间处理UI内容。我会使用经典window.setTimeout,但这个时间最短,我不想浪费时间。

1 个答案:

答案 0 :(得分:7)

event.origin不是窗口对象。这是一个URI。

event.source是源窗口对象。

如果您检查:

,您似乎可以将邮件限制为仅限于您自己
event.source === window

postMessage的MDN doc说明了这一点:

  

任何窗口都可以随时在任何其他窗口上访问此方法   无论窗口中文档的位置如何,都要发送一个   信息。因此,任何事件侦听器都用于接收消息   必须首先检查邮件发件人的身份,使用   来源和可能的来源属性。这不能低估:   无法检查原点和可能的源属性   跨站点脚本攻击。

我会解释这意味着你还应该检查一下event.origin是否至少与你的域匹配,如果你只是希望将消息发送到同一个窗口,它甚至可能与你的确切URL匹配。

您可以使用以下代码检查原点和来源:

window.addEventListener("message", function(e) {
    if (window.location.href.indexOf(e.origin) === 0 && e.source === window) {
        // passed safety check, OK to process here
        console.log("passed");
    }
});

工作演示:http://jsfiddle.net/jfriend00/j3A8k/


我想知道你是否在这里过于复杂,试图用setTimeout()来节省4ms。从postMessage的MDN页面:

  

如果您不希望从其他网站接收消息,请不要添加   消息事件的任何事件侦听器。这是完全万无一失的   避免安全问题的方法。


在你的评论中,你似乎表明你这么做很多,这就是你担心4ms的原因。你还没有说过你试图解决的实际问题是什么,但你应该能够做一些有意义的工作(例如几秒钟的工作),然后用setTimeout()收益做更多的工作。或者,如果你真的想在后台工作,也许webWorkers是一种更好的方法。