B.3.1 The __proto__ pseudo property

Kevin Gadd kevin.gadd at gmail.com
Tue Apr 23 05:59:41 PDT 2013


Aren't sandboxed natives a JS technique that actually relies on cross-realm
prototype chains?

http://msdn.microsoft.com/en-us/magazine/gg278167.aspx

My understanding is that they create a separate origin in order to get
their own copies of the natives so that they can fiddle with those natives'
prototypes without polluting the current page's global namespace/natives.
If you were to restrict prototype chains to only containing same-realm
objects, that seems like it would break any application that currently uses
a technique like this. Or is the intent that realms are a new complement to
the cross origin policy, and all iframes in a HTML document would share a
realm?


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

>
> On Apr 23, 2013, at 3:31 AM, Mark S. Miller wrote:
>
> On Mon, Apr 22, 2013 at 1:15 PM, Allen Wirfs-Brock <allen at wirfs-brock.com>wrote:
>
>> We don't currently have the concept of an object "belonging" to a realm.
>>  Functions have a realm association, but not non-function object.
>>
>
> The current idea on how to solve the security issue with weak references
> (and AFAIK the only solution that has been suggested) assumes that objects
> are identified with the realm of their creation, so that we can distinguish
> intra-realm vs inter-realm pointing. I will let others speak of the
> implementation cost. Here, I'll see if we can define a simple semantics for
> an object's realm of origin.
>
> * We agree that functions are identified with a realm. An object literal
> within a function should evaluate to an object in the same realm as that
> function.
>
> * Various built-in functions, notably Object.create but also, e.g.
> Array.prototype.map, create objects. For each such "Chapter 15" builtin
> function, again the object should be created in the realm of the function
> that creates it.
>
> What other cases are there? (I thought it would be a longer list ;).)
>
>
> There a many syntactic constructs that allocated objects (class
> definitions, template strings, comprehensions, anything that does a
> ToObject, etc. Also, many ES6 chapter 15 functions (including all the
> @@create methods) allocate objects.   In both cases, the actual allocations
> are usually indirected through abstraction operations.
>
> All ECMAScript functions and all chapter 15 built-ins belong to a realm
> and when such functions are called its realm is recorded as part of a new
> execution context (in ES6, calling a built-ins is specified to create a new
> execution contexts).  By the time the ES6 spec. is completed, I'm sure that
> ECMAScript scripts will also belong to realms and have execution contexts.
> Calling abstract operation don't create execution contexts.  So, every
> specified way to create an object occurs within the scope of  an execution
> context that is associated with a specific realm.  (however, host or
> implementation provided exotic function objects that don't use the ordinary
> [[Call]]  are unspecified and might be implemented to do something that
> doesn't including creating a new execution context).
>
> So I'm not particular concerned about the specification complexity of
> associating every object with a realm.  However, I do think that potential
> implementation impacts should be studied very carefully.
>
> Even if we had per object realm associations, it isn't clear to me what
> exactly we are trying to block WRT cross-realm [[Prototype]] chains.  Is
> the assertion that all objects in a [[Prototype]] chain must come from the
> same realm.  Does that mean that we must block creating such chains via
> Object.create or class declarations or classic constructor functions.  It
> isn't clear to me why such cross-realm chains are necessarily evil.  It
> also isn't clear to me why __proto__ should be prevented from creating them
> if we don't also prevent all other ways of doing so.  In that case, the
> appropiate place to put semantic restrictions on prototype chain
> construction/modification is in the semantics of the ordinary object
> [[SetInheritance]] internal method rather than in individual built-in
> functions and abstract operations that invoke [[SetInheritance]].
>
>
> Allen
>
>
>
>
>
>
>
>
>
>>
>> Object.create(parent);    //we have no way to determine if parent
>> "belongs" to the same realm as Object.create.
>> we also currently have no way to determine whether the caller of
>>  Object.create is in the same or different realm as Object.create.
>>
>> someObject.__proto__  = someParent;  //the setter function from
>> Object.prototype has no way to determine a realm association for someParent.
>>
>> let protoSetter = Object.getOwnPropertyDescriptor(Object.prototype,
>> "__proto__");  //a proto setter from some realm
>>
>> let x = {};
>> protosetter.call(x, another);    //no realm info to validate.
>>
>> protosetter is essentially a universal setPrototypeOf function.
>>
>> The only way I see to tame any aspect (for example not allowing
>> Object.prototype.__proto__ = something) of __proto__ setting is via a
>> [[Set]] over-ride on Object.prototype.
>>
>> Allen
>>
>>
>>
>> On Apr 22, 2013, at 7:29 AM, Andreas Rossberg wrote:
>>
>> > On 22 April 2013 15:49, Brendan Eich <brendan at mozilla.com> wrote:
>> >>> However, in that case, I actually think that there is no need to have
>> >>> any special poisoning semantics when reflecting __proto__ -- mainly
>> >>> because the cross-realm check is already necessary in the unreflected
>> >>> case: you can construct an object o in realm A with an
>> >>> Object.prototype from another realm B on its proto chain. If you
>> >>> deleted __proto__ on realm's A Object.prototype, I don't think it
>> >>> should still be possible to assign to o.__proto__, should it?
>> >>
>> >> Why not, if in realm A we evaluate 'var o =
>> >> Object.create(B.Object.prototype)'? You specified 'delete
>> >> A.Object.prototype' happened, and A.Object.prototype is not on o's
>> proto
>> >> chain.
>> >
>> > My understanding of the motivation for poisoning was to enable the
>> > deletion of O.p.__proto__ when configuring a realm as a means for
>> > guaranteeing that no object from that realm can ever have its
>> > prototype mutated. Allowing the above case would seem to shoot a hole
>> > into that.
>> >
>> >  // Realm A
>> >  delete Object.prototype.__proto__  // no messing around
>> >
>> >  let other = getObjectFromSomewherePotentiallyAnotherRealmB()
>> >
>> >  let p1 = Object.create(other, {a: {value: 1}})
>> >  let o = Object.create(p1)
>> >  let p2 = Object.create({})
>> >  o.__proto__ = p2  // say what?
>> >
>> >
>> >>> Whether a
>> >>> difference should be made between quoted and unquoted I don't know, I
>> >>> must have missed the rationale for such a move.
>> >>
>> >> I think we're not going to induce vomiting by making a quoted vs.
>> unquoted
>> >> distinction, in light of Mark's point about computed property names.
>> >
>> > OK, good. :)
>> >
>> > /Andreas
>> > _______________________________________________
>> > es-discuss mailing list
>> > es-discuss at mozilla.org
>> > https://mail.mozilla.org/listinfo/es-discuss
>> >
>>
>>
>
>
> --
>     Cheers,
>     --MarkM
>
>
>
> _______________________________________________
> es-discuss mailing list
> es-discuss at mozilla.org
> https://mail.mozilla.org/listinfo/es-discuss
>
>


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


More information about the es-discuss mailing list