Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Safe use of window.postMessage, is "if ( event.source !== window){return;}" alright?

I'd like to use window.addEventListener("message",myOnmessageCallback,false) for receiving messages only coming from my window itself. (this is to say I do not want to needlessly make the myOnmessageCallback function prone to be receiving malicious messages from some other sources (I assume such might be other frames, browsersWindows, tabs, parent and iframes, right?).

Therefore I thought, if this avoid touching anything from not my window itself.

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

Does this seem a good way to reduce the myOnmessageCallback callback for just dealing with messages send via window.postMessage() of the webpage itself?

PS: For those who think why I desire such reduced postMessage onmessage capabilities. I want to have a way to put something in the Javascript execution Queue, allowing the handling of UI stuff in between. I would use the classical window.setTimeout but this has the minimum time and I do not want to needlessly waste time.

like image 882
humanityANDpeace Avatar asked Feb 14 '23 09:02

humanityANDpeace


1 Answers

event.origin is not a window object. It's a URI.

event.source is the source window object.

It does appear that you can limit messages to be only from yourself if you check:

event.source === window

The MDN doc for postMessage states this:

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.

I would interpret this to mean that you should also check to see that event.origin matches at least your domain and perhaps even that it matches your exact URL if you're only expecting to send messages to the same window.

You can check both origin and source with code like this:

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");
    }
});

Working demo: http://jsfiddle.net/jfriend00/j3A8k/


I wonder if you're overcomplicating things here to try to save 4ms with setTimeout(). From the MDN page for postMessage:

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.


In your comments, you seem to indicate you're doing this a LOT and that's why you're worried about 4ms. You haven't said anything about what your actual problem is that you're trying to solve, but you should be able to do a meaningful amount of work (e.g. several seconds worth of work), then yield with setTimeout() then do some more work. Or, if you really want to do work in the background perhaps webWorkers are a better way to do this.

like image 106
jfriend00 Avatar answered Feb 17 '23 02:02

jfriend00