Another de-facto insecurity we need to fix in ES5

Brendan Eich brendan at mozilla.com
Mon Jun 15 21:23:12 PDT 2009


For ES5, this is a tempest in a teapot.

We at Mozilla are trying to remove assignable __proto__ in a near-term  
release, except in these two useful and (AFAIK) safe cases:

* A newborn with no other properties.

* A recent-born in the midst of initialization via evaluation of its  
object initialiser syntax, where the baby object can't escape, can't  
be referenced to make a cycle, etc.

We really don't want to continue supporting mutating __proto__ in  
other cases. Assignable __proto__ is a hugely expensive operation that  
breaks all sorts of optimizations, requiring fairly expensive  
deoptimization effort.

ES5's Object.create relieves the need for any of this, but legacy code  
won't be rewritten all at once, so we're probably going to support the  
above two bulleted cases.

The idea that the ES5 spec suddenly makes the world more secure by  
trying circuitously to address old extensions such as __proto__ seems  
optimistic to me. Better to get rid of the offending extension than  
try to fence it while not speaking its (I mean ES-unspecififed  
__proto__'s) name.

But this is a job for implementors, not the spec. Implementors jumped  
in when the standards process stalled after ES3. Blame them for  
trying, or failing to design high-integrity APIs, but it's all spilled  
milk. They need to clean it up, 'sall (I say this as one of "them").

The bigger picture must involve implementations as well as the spec,  
and de-facto standards that may precede de-jure replacements or  
adoptions of de-facto standards. It isn't as if ES5 is the last time  
there will be a de-facto mess to clean up, although members of the  
committee are making good promises and progress in sharing intentions  
and prototypes. I suspect we'll see some de-facto stuff come out of  
one or two vendors who aren't active in TC39 (Apple, Google V8).

Beyond this point, implementations will have bugs, whether in would-be  
de-facto extensions to the standard, or in standardized components --  
forever. Attempts to inject security by code transformations (which of  
course can themselves be buggy) will simply have to try to work around  
browser JS engine bugs.

Security is never done, because it consists of end-to-end and many- 
layers property enforcement problems, where the evolving system and  
economic scarcity mean the bad guys always have a new layer or middle- 
man that's under-defended to attack. Denning said this in her 1999  
Infosec award speech, and it seems unassailable, even if it outrages  
some of my academic research friends.

Better JS security will have to come from the browsers fixing bugs and  
breaking compatibility, where the alternative is an ongoing security  
hazard that's actually exploited. When it comes to both bad old  
default security policies, and some of the extensions added over the  
years, I say: break the web, or at least bend it! My new mantra.  
Shocking, I know, but with minority-share browsers now getting close  
to modern-IE by-version market share, isn't it time?

/be

On Jun 15, 2009, at 8:28 PM, Allen Wirfs-Brock wrote:

> On the surface, this seems fairly reasonable., of course IE doesn’t  
> have any skin in the mutable __proto__ game.
>
> Would you really associate this with Object.freeze or would you make  
> it a characteristic of the [[Extensible]] internal property  being  
> false? Personally, I’d probably  be inclined to go with the latter.
>
> My one concern also relates to you other message concerning  
> debugging APIs.  Does no modification of [[Prototype]] really mean  
> never.  I certainly can envision debugger APIs or other support for  
> incremental/evolutionary development tools that could make use of a  
> mutable [[Prototype]] (as well as mutability of other immutable  
> states such as a false [[Extensible]] internal property) .  I’m  
> quite happy to agree that these items should not be directly mutable  
> from the internal perspective of an application program but I’m less  
> willing to agree that a “privileged” tooling API (including possibly  
> a mirrors reflection  based API) could never mutate such state.
>
> From: es-discuss-bounces at mozilla.org [mailto:es-discuss-bounces at mozilla.org 
> ] On Behalf Of Mark S. Miller
> Sent: Monday, June 15, 2009 7:52 PM
> To: es-discuss; es5-discuss at mozilla.org
> Subject: Another de-facto insecurity we need to fix in ES5
>
> As I just mentioned on the debugging API thread, at the last  
> EcmaScript meeting we agreed
>
> On Mon, Jun 1, 2009 at 5:11 PM, Waldemar Horwat  
> <waldemar at google.com> wrote:
> Rather than describing the evil things that implementations do with  
> F.caller, we agreed to just impose a blanket prohibition of code  
> peeking into the environment records or identity of strict functions  
> on the stack.  This way a test suite can ensure that F.caller does  
> nnot reveal strict functions without us having to introduce the evil  
> things into the standard.  I'll write up proposed wording.
>
> This is an example of a more general principle. The language we're  
> evolving from isn't ES3, it's ES3 as currently practiced. When  
> browser vendors implement ES5, they won't actually implement ES5 as  
> speced. They will implement ES5 as extended to preserve some of the  
> defacto practices they currently support. When these likely future  
> defacto extensions would lose some of the integrity or security  
> gains we're trying to achieve with ES5, then we should find an  
> adjustment to the ES5 spec that does not break these defacto  
> practices for old code but still allows new code to defend itself  
> from attackers using these defacto extensions.
>
> The ES3 and ES5 specs both specify the implicit [[Prototype]]  
> property as something that is initialized once and then unchanged.  
> All major browsers today but IE alias this to the name  
> "__proto__" (as if that's a named property) and allow it to be  
> mutated. None of the rest of the ES5 semantics has been critically  
> examined in light of the possibility that an implementation may  
> allow this mutation. So long as [[Prototype]] is pervasively  
> mutable, then most interesting behavior of an ES5 object won't be  
> stable as well. I recommend:
>
> Object.freeze(foo) guarantees not only that all of foo's named  
> properties be frozen and that foo is non-extensible, but also that  
> foo's [[Prototype]] will not be changed.
>
> For non-frozen objects, we continue not to specify that  
> [[Prototype]] can be mutated or explain any means for mutating it.  
> But neither can we prohibit such mutations unless FF, Safari, and  
> Opera are willing to give up this feature. The proposal above won't  
> break any old code that depends on mutating __proto__ but will  
> enable new code to protect itself. I would like to propose something  
> stronger, but don't know of anything stronger compatible with this  
> constraint.
>
> -- 
>    Cheers,
>    --MarkM
> _______________________________________________
> es-discuss mailing list
> es-discuss at mozilla.org
> https://mail.mozilla.org/listinfo/es-discuss

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.mozilla.org/pipermail/es-discuss/attachments/20090615/7b789edb/attachment.html>


More information about the es-discuss mailing list