[whatwg] Behavior when <script> is removed from DOM

Mark S. Miller erights at google.com
Thu Dec 8 15:15:30 PST 2011


On Thursday, December 8, 2011, Yehuda Katz wrote:

>
> Yehuda Katz
> (ph) 718.877.1325
>
>
> On Thu, Dec 8, 2011 at 9:23 AM, Mark S. Miller <erights at google.com<javascript:_e({}, 'cvml', 'erights at google.com');>
> > wrote:
>
>> Given only that the JSONP response has a ACCESS-CONTROL-ALLOW-ORIGIN:*
>> header, the API you suggest below can be fully implemented as a library.
>>
>> Since any response that parses as JavaScript has no same origin
>> protection anyway, rather than carve out a special case for JSONP, should
>> we waive the ACCESS-CONTROL-ALLOW-ORIGIN:* requirement on responses that
>> parse as JavaScript for XHR requests in general? If not, what justifies
>> carving out a special case for JSONP?
>>
>
> In the general case, executed JavaScript does not expose the content.
>

The legacy content we're concerned with is written to work on ES3 browsers.
By overriding "Object" and "Array", or by other subterfuge, you can corrupt
an ES3 environment adequately to violate the confidentiality of scripts
loaded later into the same frame. Anne Van Kesteren pointed out the only
form of confidentiality we can be confident of in this context: comments
(and whitespace and choice of internal variable names). Are these secrets
worth giving up on the safety that could result from loading these scripts
as data, so that we could then run them in a restricted manner (whether by
translation, verification, or other tricks, e.g., SES)?



> Existing JSONP implementations obviously work as libraries, but
> implementing them robustly is non-trivial. Given that we know that this
> subset is already secure (or at least, doesn't add any new security
> issues), creating an explicit API that eliminated the library fiddliness
> (and need for registering a global function) would be great.
>

That you say "registering a global function" leaves me suspecting you don't
understand my suggestion. Assuming ES5 and some form of origin-independent
or cross-origin xhr, very simple JavaScript code can fetch the JSONP
payload as data, strip the prefix and suffix, and use JSON.parse on the
remaining string. I mean, c'mon, it's probably a one liner. Do we really
need to add a new special case to the security architecture of the browser
in order to avoid this one liner?



>
>
>>
>>
>> On Wed, Dec 7, 2011 at 5:20 PM, Jonas Sicking <jonas at sicking.cc> wrote:
>>
>>> On Wed, Dec 7, 2011 at 3:55 PM, Yehuda Katz <wycats at gmail.com<javascript:_e({}, 'cvml', 'wycats at gmail.com');>>
>>> wrote:
>>> >
>>> > Yehuda Katz
>>> > (ph) 718.877.1325
>>> >
>>> >
>>> > On Wed, Dec 7, 2011 at 3:43 PM, Jonas Sicking <jonas at sicking.cc>
>>> wrote:
>>> >>
>>> >> On Wed, Dec 7, 2011 at 12:39 PM, Yehuda Katz <wycats at gmail.com<javascript:_e({}, 'cvml', 'wycats at gmail.com');>>
>>> wrote:
>>> >> > Yehuda Katz
>>> >> > (ph) 718.877.1325
>>> >> >
>>> >> >
>>> >> > On Wed, Dec 7, 2011 at 12:29 PM, Boris Zbarsky <bzbarsky at mit.edu<javascript:_e({}, 'cvml', 'bzbarsky at mit.edu');>>
>>> wrote:
>>> >> >
>>> >> >> On 12/7/11 3:22 PM, Joshua Bell wrote:
>>> >> >>
>>> >> >>> This can't be implemented in JS today (e.g. as a shim) since that
>>> >> >>> "evaluate
>>> >> >>> this script text in this new global sandbox" bit isn't present.
>>> >> >>>
>>> >> >>
>>> >> >> It can sort of be done via opening a new window and setting its
>>> opener
>>> >> >> to
>>> >> >> null before injecting some <script> tags into it.  Modulo popup
>>> >> >> blockers
>>> >> >> and crappy user experience, of course....
>>> >> >
>>> >> >
>>> >> > Or evaluating the script inside a worker, perhaps?
>>> >>
>>> >> Workers aren't great sandboxes. They already have access to shared
>>> >> workers and XHR. Soon they will get access to IndexedDB too. So
>>> >> there's lots of damage they can cause.
>>> >>
>>> >> If we want to run untrusted code then I think we need to have an API
>>> >> specifically designed for that.
>>> >>
>>> >> If we want an API for loading JSONP data apart from the sandbox (which
>>> >> I think is needed), then we should have an API specifically designed
>>> >> for that. It's possible that we can reuse XHR here and just adjust the
>>> >> security model when the returned data is JSONP.
>>> >
>>> >
>>> > You would at least want to execute them in a lexical scope containing
>>> the
>>> > callback, so that the callback did not need to be installed on the
>>> global
>>> > scope.
>>>
>>> Ideally we wouldn't execute anything. We'd just parse the JSON literal
>>> and hand that back. That is what'll give us safety.
>>>
>>> To make a concrete, but hideous, example:
>>>
>>> We could add xhr.responseType = "jsonp".
>>>
>>> When this is set, the XHR object will look for contents on the following
>>> form:
>>>
>>> <js identifier> '(' <js-literal> ')'
>>>
>>> followed by an optional ';'
>>>
>>> When the contents follows that syntax, the XHR object parses the
>>> js-literal and sets it's .response property to the result.
>>>
>>> Other than that the XHR object works just as it currently does. I.e.
>>> it fires progress events, load events and readystatechange events as
>>> normal.
>>>
>>> This way no JS execution happens, and no global names need to be set
>>> up. The <js identifier> part is simply ignored other than to check
>>> that it's a valid js identifier.
>>>
>>> I believe we can come up with something better than this, but it's a
>>> demonstration of what's technically feasible.
>>>
>>> / Jonas
>>>
>>
>>
>>
>> --
>>     Cheers,
>>     --MarkM
>>
>
>

-- 
    Cheers,
    --MarkM



More information about the whatwg mailing list