[whatwg] sandboxing scripts

Alexey Feldgendler alexey at feldgendler.ru
Thu Dec 15 21:48:36 PST 2005

On Thu, 15 Dec 2005 19:11:13 +0600, Hallvord R M Steen  
<hallvors at gmail.com> wrote:

> Just playing around with ideas for other security models for SCRIPT.

Your ideas seem reasonable. JS security is something that has been long  
awaiting to be addressed.

> 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. With your  
approach, any existing browser will just ignore the unknown "sandbox"  
attribute, effectively allowing the script to do anything. This is not  

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

3. There are still HTML attributes like "onclick", and javascript: URIs  
that are not addressed.

> 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.

Here is my idea, then.

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.

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.

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 example, LiveJournal can specify synthetized subdomains like  
<user>.livejournal.com for entries by each user.) If there is no "domain"  
attribute, then the inner JS doesn't have access to any cookies.

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.

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.

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

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

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>.

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

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.

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  

7.3. A new URI scheme is introduced: "safe-javascript:". Likewise.

-- Opera M2 9.0 TP1 on Debian Linux 2.6.12-1-k7
* Origin: X-Man's Station at SW-Soft, Inc. [ICQ: 115226275]  
<alexey at feldgendler.ru>

More information about the whatwg mailing list