[whatwg] Request: window.postMessage should be async

Eric Seidel wrote:
> 1.  JS content authors will want an async API.

Sometimes, for the large applications; small apps won't care.  As you note, the workaround of immediately packaging up a setTimeout continuation isn't difficult.  I tend to think worrying about the N-1 case is designing a bit too much for the special cases, personally.  Special cases aren't special enough to break the rules.[0]  Further, nothing says browser implementations must or will continue to enforce hard limits on recursion.

> function messageHandler(messageEvent) {
> // We assume calling into our complex functions might run out of stack 
> space, so we just handle this in a timeout:
> setTimeout(0, function() { realMessageHandler(messageEvent) } );
> }
> 
> function realMessageHandler(messageEvent) {
>  // handle the message...
>  // and, reply to the message
>  messageEvent.source.postMessage("response message");
> }

Furthermore, note that the above behavior is actually *insecure* if the handler authenticates the sender and discloses some secret in his response, because |messageEvent.source| may have been navigated to a different origin.  Making the API async basically requires the optional origin argument always be provided to postMessage, adding API complexity.  If a piece of information doesn't have to be [present] for the system to [usually] work, sooner or later it won't be [and the system won't work].[1]


> I forsee JS authors implementing their own asynchronous behavior, as 
> shown above.

I do, too, in some cases; I just don't think it's worth sacrificing simplicity or security in the common case for the special, rare case.


> 2.  JS engine implementors will want an async API.

> I would rather we didn't prevent FireFox or Safari

"Firefox", the second "f" isn't capitalized.  :-)
 
> (Only possible for frames which are not of the same origin.   Same-origin
> frames already assume they can grab at each others innards in a 
> synchronous manner.)  postMessage imposes a NEW requirement that all 
> connected frames to be run from the same thread (or somehow synchronize 
> the threads after the first postMessage() call is made).

Wrong; if a window can get a reference to another window, same-origin or not, run-to-completion already requires synchronous behavior.  If some piece of JS is in flight, every client-side change it can detect *must* be one it has caused.

> This requirement would seem even worse for Microsoft, since IE8 looks like 
> it's multi-process.  A synchronous postMessage would require IE8 to keep 
> all frames which have references to each other in the same process.

postMessage imposes no new requirement for the appearance of synchrony, no matter how the implementation chooses to achieve it.


Asynchrony was brought up in a separate thread ("[whatwg] reply() extension to postMessage()") two months ago, before the source-navigation discussion made this secret-exposure danger more easily noticeable.  I made basically the same arguments then as I make now; I also noted that sync can replicate async (again ignoring the uncommon case of being right at the recursion limit), whereas the reverse is not true:

> I think I favor sync postMessage over async because async capabilities 
> are a strict subset of sync capabilities.  You can always use setTimeout 
> with the sync model to get async behavior; if the model is async you 
> can't replicate sync behavior.

Note also that nothing prevents an implementation with a recursion limit from requiring that postMessage always guarantee enough available frames to dispatch the setTimeout continuation, although nobody I know has actually done this.


In sum, I think worrying about recursion limits is the wrong thing to do, sync behavior is more flexible, and we shouldn't sacrifice security for the uncommon recursion-limit case.

Jeff

0.  Python, thy name is AWESOME.  <http://www.python.org/dev/peps/pep-0020/>
1.  Astonishingly PEP 20 doesn't have any dicta related to security, but <http://www.wiretip.com/?about> comes to the rescue, with a few tweaks.

Received on Friday, 4 April 2008 15:07:12 UTC