Another de-facto insecurity we need to fix in ES5

Brendan Eich brendan at mozilla.com
Thu Jun 18 01:06:14 PDT 2009


On Jun 17, 2009, at 3:34 PM, Mark S. Miller wrote:

> On Mon, Jun 15, 2009 at 9:23 PM, Brendan Eich <brendan at mozilla.com>  
> wrote:
> For ES5, this is a tempest in a teapot.
>
> We at Mozilla are trying to remove assignable __proto__ in a near- 
> term release,
>
> Hi Brendan, this is wonderful news!
>
> As reason for skepticism, our v8 folk cite
>
> <http://www.google.dk/codesearch?q="__proto__+%3D+"+lang:javascript>

First page has a lot of Mozilla-only code, of course; I see caja.js at  
top of second page. We both should evangelize ES5 Object.create when  
it's ready.


> Nevertheless, I'm pleased to report that our v8 folks agree that if  
> Mozilla does this and does not back off because of compatibility  
> problems, they will do so as well. Thanks for being brave enough to  
> jump into this pool first!

Water's fine, really!


> * A newborn with no other properties.
>
> For an object that never comes to have any own properties, when is  
> it no longer a newborn?  For example
>
>     function Token() {}
>     var tok = new Token();

I didn't define that case fully, but what I had in mind was an object  
that has not yet gained "own" properties. Such an object might be  
accessible outside of a lexical scope, though, you're right. If that's  
a problem then escape analysis, which we are looking at for stack- 
based GC, might rescue this idea.


> * 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.
>
> How does this arise?

var obj = {foo: 42, __proto__: bar};

Here the object has own properties, foo in this case. But it can't be  
referenced until after the entire initialiser has been evaluated.


> In both cases, would it be true that by the time Object.freeze(x) or  
> Object.preventExtensions(x) returns that x no longer has a mutable  
> [[Prototype]]?

Yes, I agree with you about false [[Extensible]] making [[Prototype]]  
immutable. Nothing else makes sense.


> 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.
>
> Given that this already isn't a problem for IE and Opera, that v8  
> follows your lead, and assuming that Apple does as well -- so that  
> these two remain the only exceptions -- do you recommend that the  
> spec adopt stronger wording? (I would find this attractive as well.)  
> Any suggestions for what this stronger wording might be?

It's too late for ES5. It would not necessarily have the effect we  
hope for, anyway. We need to try restricting assignments to __proto__  
and see how that flies.


> 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.
>
> Certainly! But until we see how your experiment goes (best of luck!)  
> I am proceeding under the pessimistic assumption that we can't get  
> rid of the offending extension from all ES5 implementations. I'd  
> love to be proven wrong.

We seem to agree, then. This is a matter of implementors reforming  
implementations, then the spec can follow.


> When implementations have bad features in common with each other,

First, there are bad features in ES1-3 not in all implementations of  
those specs' eras. Nothing in the spec process magically precludes  
"bad", alas.

Second, bad de-facto standards may be too expensive to codify in a  
given period (including ES5, especially now). But that doesn't mean  
implementors can't launch reform initiatives, or web developers can't  
start reform movements.

Third, even if we could afford to simultaneously specify and deprecate  
or restrict (e.g., ban from strict mode) bad old forms in a next-gen  
de-jure standard, if there's no better way for developers to solve the  
problems they solved with the bad old forms, at least until the next- 
gen standard is adopted widely, then developers won't tolerate browser  
vendors breaking the platform the devs built upon, which the browser  
vendors purveyed.

I've written about using the carrot, then the stick. But the  
metaphor's wrong: TC39 or another standards body is no horse trainer,  
and developers are not horses. The mistakes made everywhere should  
motivate greater humility, in addition to staging of de-jure standards  
based on de-facto work.


> as
> with F.caller, then some cross-browser code will have come to rely on
> that feature. Then, even if each browser vendor individually  
> believes that the web
> would be better off without that feature, they are in the normal
> browser competitive bind removing the feature. That's one of the major
> purposes of standards committees -- to get de-jure agreement on
> changes that all would like to make but that each would be punished
> for making by themselves. I think this accurately describes why we
> needed a de-jure poison pill for F.caller.

It's plausible; I've talked about the Prisoner's DIlemma at work in  
the browser market.

However, until widely adopted, a "reformist" de-jure standard is  
toothless. In the present case it is Mozilla (and others who'll join  
us) who must take risk in the market trying to restrict assignable  
__proto__. Ecma TC39 via ES5 (even if it had started the effort in  
time) couldn't credibly ban assignable __proto__ in non-strict mode.


> Given the expanded threat model ES5 seems to enable (see the "Future  
> defensibility from untranslated code" section at the bottom of <http://code.google.com/p/google-caja/wiki/NiceNeighbor 
> >), the F.caller issue, had it not been caught in time, would have  
> cost us a factor of two in performance. The present issue, if  
> unfixed, may well preclude this expansion of our threat model except  
> on ES5 implementations that happen not to have this problem.

I'm glad this was caught. We're just getting into strict mode  
implementation now, and we have an old access check in the  
SpiderMonkey F.caller code (Norris Boyd added this in the late '90s,  
for Netscape's signed script/applet security model), as I mentioned at  
the TC39 meeting. This suggests reviewing all access checks for strict  
mode relevance.

/be
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.mozilla.org/pipermail/es5-discuss/attachments/20090618/00e4b2f4/attachment-0001.html>


More information about the es5-discuss mailing list