Membranes, unmediated access to objects through Object.getPrototypeOf

Tom Van Cutsem at
Mon Oct 8 09:29:12 PDT 2012

Hi David,

I really don't think this is an "elephant in the room". We've encountered
this before. The issue you point out is exactly the same issue with regard
to the "get" trap having to return an identical value (as per
[[SameValue]]) for non-configurable own properties of the target.

The solution for wrapping non-configurable own properties was to introduce
a "dummy" target on which to store wrapped versions of the properties. The
solution to wrapping [[Prototype]] is to similarly use a dummy target whose
prototype is the wrapped prototype of the real target.

Indeed, one of the other reasons for introducing a "getPrototypeOf" trap
was so that membranes could properly "sync" the dummy's [[Prototype]] with
the target's [[Prototype]] in the face of mutable prototypes.

Your proposed alternative involving the target-chain is the solution
employed by Racket chaperones [1]. Mark and I have been hesitant to use
this solution as it violates invariants pertaining to object-identity in
Javascript. For example, using the current proxy spec and assuming no
mutable __proto__ (e.g. Object.prototype.__proto__ was deleted), you're
guaranteed that Object.getPrototypeOf(obj) always returns the same (as per
"===") object. The chaperone solution voids that guarantee.

Finally, note that a "naively implemented" membrane that just always wraps
the prototype, without using a dummy target, would still not have leaked
any references: this code would instead trip on the assertions that protect
the "getPrototypeOf" trap as it tries to return a wrapped prototype.



2012/10/8 David Bruant <bruant.d at>

> Hi,
> Proxies enable the implementation of membranes [1]. It's one motivating
> use case of proxies. Useful membranes mediate access to every object which
> was reach from another object in the membrane.
> I realize now that Object.getPrototypeOf violate this principle in harmful
> ways:
>     function C(){}
>     var wrappedC = wrap(C);
>     // Thanks to the wrapping get trap, we have:
>     wrappedC.prototype !== C.prototype
>     // Now, consider:
>     var wrappedCInstance = new wrappedC(); // created a cInstance as target
>     // Because of the getPrototypeOf invariant, we have:
>     Object.getPrototypeOf(wrappedCInstance) ===
> Object.getPrototypeOf(cInstance)
>     // worse:
>     Object.getPrototypeOf(wrappedCInstance).constructor === C // and not
> wrappedC !!
>     // It's still possible to delete C.prototype.constructor for this
> case, but
>     // the least undeleted .constructor can yield unsecure code...
> Basically, the getPrototypeOf invariant provides unmediated access to
> prototype objects which sounds like an abusive amount of authority.
> I suggest to revise the getPrototypeOf invariant from
>     "the trap result must me target.[[Prototype]]"
> to:
>     "the trap result must be either target.[[Prototype]] or a proxy which
> has target.[[Prototype]] in its target chain"
> For the definition of "target chain" (or "proxy chain"):
> This new definition would enable wrapping Object.getPrototypeOf calls and
> allow preserving the following equality:
>     Object.getPrototypeOf(new wrappedC()) === wrappedC.prototype
> because as the proxy proposal is, this equality cannot be true any longer.
> This flaw was here since the original proxy design in which
> Object.getPrototypeof was untrapped and I think justifies in itself the
> addition of the getPrototypeOf trap regardless of the whole __proto__ story.
> This flaw gives me an impression of "elephant in the room" that we've
> missed.
> Over time, I've gained a certain level of intimacy with the proxy spec and
> I can't help having this feeling of "what else are we missing?". I don't
> have the answer, i'm still searching, but if we've missed this elephant the
> whole time, I can't help thinking that the proxy spec needs more attention.
> David
> [1]
> _______________________________________________
> es-discuss mailing list
> es-discuss at
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <>

More information about the es-discuss mailing list