[whatwg] The choice of script global object to use when the script element is moved

Henri Sivonen hsivonen at iki.fi
Tue Sep 7 01:40:37 PDT 2010


NOTE! This email contains URLs to pages that crash WebKit on reload, so you probably shouldn't follow the URLs here in any WebKit-based browser where you have something important going on in the same renderer process. (In Chrome, only the isolated content process crashes.)

> On Fri, Sep 3, 2010 at 3:49 AM, Henri Sivonen <hsivonen at iki.fi> wrote:
>> When evaluating a parser-inserted script, there are three potential script global objects to use:
>>  1) The script global object of the document whose active parser the parser that inserted the script is.
>>  2) The script global object of the document that owned the script element at the time of invoking the "run" algorithm.
>>  3) The script global object of the document that owns the script element at the time of script evaluation.
>> 
>> The spec says the answer is #3. WebKit (with HTML5 parser or without) says the answer is #1. Firefox 3.6 says the answer is #2.

On Sep 3, 2010, at 20:47, Adam Barth wrote:

> I'm not sure it makes much of a difference from a security point of
> view.  I suspect WebKit does #3 because it grabs the security context
> immediately before executing the script.  

With my demos, WebKit seems to be doing #1:
http://hsivonen.iki.fi/test/moz/move-during-parse-parent.html
http://hsivonen.iki.fi/test/moz/move-during-parse-parent2.html

The second one doesn't finish loading in Gecko (both with new and old parser), because Gecko tries to unblock the parser on the wrong document and never unblock the parser that needs to be unblocked.

> That actually seems
> marginally safer because it means you're unlikely to grab an out-dated
> security context.

Since the check "If scripting is disabled for the script element, or if the user agent does not support the scripting language given by the script block's type for this script element, then the user agent must abort these steps at this point. The script is not executed." happens at the time of the "run" algorithm and since iframe sandboxing or Content Security Policies can cause scripting to be "disabled", a security check has to happen at the time of invoking the "run" algorithm (assuming we don't want to change the pre-existing behavior of what happens in the common same-document case where a script gets rejected and we don't want to decouple the time on supported language check from the time of security-based rejections; this would be detectable in the document.write() case). 

For external scripts, this means that if we want to evaluate against a script global object associated with the owner doc of the script node at evaluating time, the security checks may have been performed in the context of another document and script global object. If we want security checks against the script global object associated with the owner doc at evaluation time, I think it's necessary to do the security checks twice: one during the "run" algorithm (in which case failing the checks doesn't fire any error events) and another time right before evaluation (in which case I suppose a failure should act the same way as a network failure and fire the error event). That's more complex than what's in Gecko now. (Not insurmountably complex, but more complex anyway.)

I'm worried about doing the security checks at "run" algorithm time and evaluating with a different script global object without redoing the security check. However, it may be that I only worry because I feel I don't know enough of all the possibilities to be confident that such a separation of time of check and time of use would be safe here.

Is there any good reason (other than differing from current IE9 PP behavior) not to do #1 with the additional stipulation that making the document whose active parser the parser is go away makes the scripts that are pending to run in the context of its script global object behave (stop?) the same regardless of which document they are in? (I.e. if the document that had the active parser gets torn down before the scripts inserted into another doc have loaded, those scripts wouldn't be evaluated.) I still believe doing #1 in Gecko would be the simplest thing. With the test cases above, WebKit seems to be doing #1 already (and then crashing) and Opera fails to move the scripts so the execution context ends up being the same as it would in case #1.

On Sep 3, 2010, at 20:55, Jonas Sicking wrote:

> On Fri, Sep 3, 2010 at 10:47 AM, Adam Barth <w3c at adambarth.com> wrote:
>> I'm not sure it makes much of a difference from a security point of
>> view.
> 
> Agreed. Pages can only move elements between pages that are in the
> same security context anyway so I can't really think of any attacks
> that any of the approaches would enable or disable.

Suppose there are two docs from one Origin. The document that the parser is associated with doesn't have a CSP. A script in it moves a node in such a way that the parser ends up inserting subsequent scripts into another document. That document has a CSP that bans scripts. Would you consider it a bug if a script ran in the context of the script global object of the document whose CSP says no scripts?

-- 
Henri Sivonen
hsivonen at iki.fi
http://hsivonen.iki.fi/





More information about the whatwg mailing list