B.3.1 The __proto__ pseudo property
allen at wirfs-brock.com
Tue Apr 23 08:52:42 PDT 2013
On Apr 23, 2013, at 5:10 PM, Mark S. Miller wrote:
> 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]].
> 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"?
just "names". In other words is it ok set the [[Prototype]] of Object.prototype to something other than null.
> 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 trouble).
> 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.
Which you would just do so by make your object's non-extensible, right? That does more than just limit setting of [[Prototype]] but it does that job too. I've previously proposed we have an independent per object immutablePrototype state which would be more targeted, but that didn't find any support.
> [*] 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.
Since you've decided it's ok to make Object.freeze, defineProperty, etc. universally available why wouldn't you also make setPrototypeOf (ie, [[ProtoSetter]]) universally available and just preventExtensions on object you need to protect from that. It it just the general distaste for __proto__ that most of us share with you?
You haven't yet convinced me that there is actually a need for these realm restrictions on [[ProtoSetter]] and for something seemingly so arbitrary we should really have a strong case for why it is important. The ES world would be simpler and cleaner within the restrictions and there would be no particular reason for not making Object.setPrototypeOf available as an alternative API for those that prefer it.
-------------- next part --------------
An HTML attachment was scrubbed...
More information about the es-discuss