javascript - 安全使用window.postMessage, "if ( event.source !== window){return;}"可以吗?

标签 javascript security message-queue postmessage

我想使用 window.addEventListener("message",myOnmessageCallback,false) 来接收仅来 self 的 window 本身的消息。 (这就是说,我不想不必要地使 myOnmessageCallback 函数容易从其他来源接收恶意消息(我假设这可能是其他框架、浏览器Windows、选项卡、父级和iframe,对吧?)。

因此我想,如果这样可以避免接触任何不是我的窗口本身的东西。

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 但这有最短的时间,我不想不必要地浪费时间。

最佳答案

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

event.source 是源窗口对象。

如果您勾选:

event.source === window

postMessage 的 MDN 文档指出:

Any window may access this method on any other window, at any time, regardless of the location of the document in the window, to send it a message. Consequently, any event listener used to receive messages must first check the identity of the sender of the message, using the origin and possibly source properties. This cannot be understated: Failure to check the origin and possibly source properties enables cross-site scripting attacks.

我认为这意味着您还应该检查 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() 节省 4 毫秒。来自 postMessage 的 MDN 页面:

If you do not expect to receive messages from other sites, do not add any event listeners for message events. This is a completely foolproof way to avoid security problems.


在您的评论中,您似乎表示您经常这样做,这就是您担心 4 毫秒的原因。您还没有说明您要解决的实际问题是什么,但是您应该能够做大量的工作(例如,几秒钟的工作),然后使用 setTimeout() 屈服 然后再做一些工作。或者,如果您真的想在后台工作,也许 webWorkers 是更好的方法。

关于javascript - 安全使用window.postMessage, "if ( event.source !== window){return;}"可以吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20526308/

相关文章:

reactjs - 在 React 应用程序中保护 Firebase API key 使其无法公开访问的最佳方法是什么?

windows - 哪种类型的特定访问权限 (ACCESS_MASK) 对 SE_LMSHARE 有效?

javascript - D3.js 堆积条形图

html - 如何在 Vim 每次保存 "source file"时自动更新或压缩 CSS、JS 和 HTML 文件?

php - Javascript 数组中的当前条目

api - 允许 Gitlab 集成的安全 Kubernetes API

javascript - 如何使 Angular ui-router 父状态在状态更改时始终执行 Controller 代码?

redis - redis/kafka如何实现禁止重复消费

ruby-on-rails - 关于 Rails 前端和 Scala 后端之间通信的建议

java - 使用java工具的类似Sidekiq的队列?