[whatwg] sandboxing scripts

Hallvord R M Steen hallvors at gmail.com
Tue Dec 27 14:18:52 PST 2005


Sorry to be slow at responding, Christmas and all that..

> > Here's what I thought: a new attribute "sandbox" (or "securitypolicy",
> > name doesn't matter much) might tell the UA something about what the
> > script can do:
> > <script src="..." sandbox="writeonly">
> > <script src="..." sandbox="none">
>
> 1. The entire thing has to degrade SAFELY in existing browsers.

I'm not absolutely sure this is a requirement, since it improves on
today's situation which *is* no security at all once you include a
script from another server.
In this context "degrading safely" means "not being
backward-compatible". You can't add a safejavascript: uri scheme
without breaking backwards compatibility, do server-side sniffing and
send different code to different browsers by UA-name, which in itself
adds so many complications that it is a security problem in its own
right.

> 2. The site author has to take care that the "sandbox" attribute is
> included in every <script> element, even in user-supplied code.

Yes. I agree that perhaps an element is a better idea, so that
everything inside could live in its own environment.

> > In all cases the limitation would apply only to the thread created by
> > that SCRIPT tag. Functions defined in those scripts might be called
> > later and would run with normal privileges.
>
> This is dangerous, too, because a malicious script can try to redefine
> common JS functions like window.alert() to do something bad.

Yes, but origin-checking every function is too complex implementation-wise.

> The primary danger of JS is that when different kinds of a single HTML
> page come from different sources (are authored by different persons). As a
> real life example, I'll take LiveJournal.com, where it's currently
> completely forbidden to include any scripts in journal entries or
> comments. They would like to allow some scripting, only if they could
> somehow separate harmless scripts from potentially dangerous ones.
>
> The idea is to add a new element, <sandbox> (the actual name doesn't
> matter much). This element can appear anywhere (in both <head> and <body>)
> and can include any elements that it's direct parent can include. It has
> no other effect on its contents than altering the contained scripts'
> security. Everything enclosed in <sandbox>...</sandbox> is somewhat
> limited in what scripts can do.

I think this idea is a clear improvement on mine :-)

> 1. All scripts inside <sandbox> are affected. This includes <script>,
> javascript: URIs, "onclick" etc. Other active objects like <object> that
> can access DOM are affected too (for example, Flash is restricted by
> <sandbox>, too).
>
> 2. The script in a <sandbox> thinks that it's god. It can do everything,
> but only inside that sandbox.
>
> 2.1. The window.document actually represents the part of document inside
> <sandbox>. Yes, it's not a valid HTML document -- with fake body element
> (window.document.body being the document fragment inside <sandbox>), and
> otherwise looking strange, but it's usable by most scripts. Other DOM
> facilities also pretend that there's nothing outside the sandbox.

Agree with all the above.

> 2.2. If the <sandbox> has a domain="..." attribute, then the scripts
> inside the sandbox have access to cookies from the specified domain, can
> interact with other sandboxes and frames from that domain, and are
> otherwise restricted in a similar way as a regular content from that
> domain (but not breaking out of 2.1 restriction). The "domain" attribute
> can only specify the domain of the containing document or a subdomain
> thereof.

For obvious reasons we can not allow a sandbox to specify
freely what domain it belongs to and change behaviour to for
example allow reading cookies or sending XMLHttpRequests to
that domain, because we have no way to verify that sandbox
contents are related to the domain it claims to be related
to. I basically agree with the restriction proposed above, I'm not
sure what exactly you mean by  "subdomain" though. Would you call
useraccount.livejournal.com a "subdomain" of www.livejournal.com ? If
the answer is yes, would you call example.org.uk a "subdomain" of
demo.org.uk, given that they also share two out of three labels?

If we say that the sandbox's domain can add server names to the parent
page's any sandbox that wants to claim it belongs to
useraccount.livejournal.com must be served from http://livejournal.com
without the www. Hard to impose such extra restrictions on existing
content.

document.domain can only be set to a dot-separated substring of
itself. We can not use that model either because we can't let content
on example.co.uk set document.domain to co.uk and contact all other
.co.uk domains.

> 2.3. The JS namespace in a sandbox is isolated. JS inside the sandbox
> cannot see the variables and functions declared outside, and vice versa.
> JS outside the sandbox can accesss JS variables and functions from inside
> the sandbox in an explicit way (like sandboxElement.sandbox['variable']).
> If the outer JS needs to make several things (DOM nodes, JS variables)
>  from the outside accessible to the inner JS, it can do so by putting
> references to these into sandboxElement.sandbox array.

Perhaps unlimited access from parent to sandboxElement.contentDocument
would do? Or should we be more concerned about limiting access from
parent to sandbox?

> 2.4. Multiple sandboxes on one page sharing the same "domain" attribute
> value share the same JS namespace (sandboxElement1.sandbox ==
> sandboxElement2.sandbox). Sandboxes without a "domain" attribute are
> always isolated.

OK, that is a good use case for the .sandbox property.

> 3. Sandboxes can be nested, with each inner one being additionally
> restricted by the outer.

Not entirely sure what you mean by "additionally restricted". We
either keep JS environments separate or not..? :-)

> 4. The script can find out that it's running in a sandbox. There's nothing
> bad about it.

Agree.

> 5. There should be a discussion about what a sandboxed script can do. Can
> it set window.location? Can it do window.open()? Maybe these permissions
> should be governed by additional attributes to <sandbox>.

Perhaps but I would rather not add too much complexity on permissions.
I'd be inclined to just set a restrictive but usable policy.
I'd disallow both window.location and window.open, and prevent sandbox
from targetting main window with form submits, link targets etc.

> 6. A sandbox can specify a single JS error handler for all enclosed
> scripts (to address known cases of scripts which are not ready for the
> unusual environment they are in).

Unsure, not all browsers support window.onerror and I'm not sure if it
is good design.

> 7. Backward compatibility. The current browsers will ignore the unknown
> <sandbox> element and give the enclosed scripts full access to everything.
> This is not acceptable. As there is no way to disable scripting inside a
> certain element in HTML 4, the HTML cleaners usually found on sites live
> LiveJournal.com are still required. Here's what they should do.
>
> 7.1. There are new elements: <safe-script>, <safe-object>, <safe-iframe>
> (did I forget something?). They are equivalent to their "unsafe"
> counterparts, except that the existing browsers simply ignore them. HTML
> cleaners should replace <script> with <safe-script> and likewise.

As I said above, this is IMO not ideal because it requires browser
sniffing and different code for different UAs. Perhaps we should go
for the simpler use cases like including untrusted advertising SCRIPT
tags before tackling the harder ones like securing user input on
LiveJournal :-)

> 7.2. HTML event handler attributes are mangled likewise: safe-onclick, for
> example. Note that this doesn't affect the names of DOM properties like
> element.onclick.
>
> 7.3. A new URI scheme is introduced: "safe-javascript:". Likewise.
>
>
> -- Opera M2 9.0 TP1 on Debian Linux 2.6.12-1-k7

I like your taste in browser and E-mail software :-)
--
Hallvord R. M. Steen



More information about the whatwg mailing list