B.3.1 The __proto__ pseudo property

Mark S. Miller erights at google.com
Tue Apr 23 08:10:52 PDT 2013

On Tue, Apr 23, 2013 at 6:30 AM, Allen Wirfs-Brock <allen at wirfs-brock.com>wrote:

> Mark, below what you refer to as [[SetProtoype]] is essentially the
> [[SetInhertiance]] MOP operations in the current spec. draft there is also
> a [[GetInheritance]].  It is called Get/SetInheritance because it doesn't
> necessarily manipulate the [[Prototype]] of the object it is invoked upon
> (eg, if it is a Proxy) and for exotic objects property inheritance isn't
> constrained to use [[Prototype]].

I knew I was using the wrong names and being sloppy about how this relates
to the actual MOP. I accept all those corrections. Thanks.

> On Apr 23, 2013, at 5:11 AM, Mark S. Miller wrote:

>  >
> > * In this initial state, Object.getOwnPropertyNames(Object.prototype)
> returns a list which includes the string "__proto__". No magic.
> >
> > * Likewise for all other reflective operations, including "in". No magic.
> So, getOwnPropertyKeys(Object.prototype) is expected to yield "__proto__"

Sure. If Object.getOwnPropertyNames returns "__proto__" wouldn't it be
bizarre for getOwnPropertyKeys not to?


> > * The behavior of [[ProtoSetter]] is approximately
> >
> >     function [[ProtoSetter]] (newValue) {
> >         if ([[GetRealm]](this) !== [[GetRealm]]([[ProtoSetter]])) {
> >             throw new TypeError(....); // or should this be RangeError ?
> >         }
> >         this.[[SetPrototype]](newValue);
> >     }
> In the past there were other restrictions that have been suggested.  For
> example, not allowing:
>    Object.prototype.__proto__ = notNull;
> to do what the above a=names suggest.

What is "a=names"?

> Regardless, what is so special about the [[ProtoSetter]] operation that it
> needs to be restricted in this way?  It's just a capability and you know
> how to control access to capabilities.  You also know how to protect
> objects from having their [[Prototype]] mutated.  If I have any object,
> that inherits from a different realm's Object.prototype I can navigate to
> its constructor property which gives me access to that other realm's,
> Object.create, Object[[@@create], and all the other Object.* functions.
>  Why isn't being able to find and  apply some other realms Object.free[ze]
> just as scary as finding its [[ProtoSetter]]?

SES includes Object.freeze in its set of universally available primordials.
Thus, an Object.freeze from a foreign non-SES-secured realm is not a threat
since Object.freeze is already universally available to confined
("untrusted") code within the local SES-secured realm.

I expect SES initialization will delete Object.prototype.__proto__ or at
least remove its setter. It is conceivable SES will hold the setter off on
the side for some special use. But regardless, it will probably[*] deny
these powers to confined code within that SES-secured realm. Thus, SES
code, including confined code, should be able to safely assume that the
[[Prototype]] of its own objects won't be mutated.

When SES code interacts only with SES code, whether intra or inter realm,
then this is the end of the story and the cross realm threat is not an
issue. But SES objects must be able to maintain their own integrity even
when exposed to non-SES objects from other frames. That was impossible for
ES5/3, the Caja translator from ES5 to ES3, since Object.freeze was
emulated, and thus only enforced for translated code. As of ES5,
Object.freeze protects unconditionally (which was why <
https://bugzilla.mozilla.org/show_bug.cgi?id=674195> gave Caja so much

So if SES code should generally be able to assume that its own
[[Prototype]]s are stable, we need to preserve the safety of that
assumption when objects from a SES-secured realm are exposed to objects
from a non-SES-secured realm.

[*] I say "probably" to hedge my bets. The hard constraint we absolutely
require is already guaranteed by ES5: That the [[Prototype]] of a
non-extensible object cannot be mutated. Given that, it is possible (though
unlikely) that SES will choose to make the setter universally available, in
which case you are correct and the inter-realm checks I'm insisting on are
for naught.

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

More information about the es-discuss mailing list