Private symbols auto-unwrapping proxies (was: Security Demands Simplicity (was: Private Slots))

Tom Van Cutsem at
Thu Jan 24 00:52:32 PST 2013

2013/1/23 David Bruant <bruant.d at>

> Le 23/01/2013 09:38, Tom Van Cutsem a écrit :
>> 3) because of JS's "invoke = get + apply" semantics, by default a proxy
>> always leaves the |this| value pointing at the proxy.
>> Looking only at 3), sometimes this is what you want, and sometimes it
>> isn't.
> In which case would it be what you want?

See the example by Brendan just upstream in this thread.

> The example Brandon (and Kevin before him) provided showed something very
> intrusive about proxies related to your 3). That proxies mediate the access
> to the public method is one thing, that they pretend to be the object acted
> on inside the method opens a entire world.
> Even with fixes suggested by Allen, the hazard can still exist if someone
> does:
>     Counter.prototype.increment.**call(new Proxy(counter,
> maliciousHandler))

I don't understand why this is a hazard. Even without proxies, |this| is
never reliable, unless you use .bind().

> I have no idea how this can be mitigated in general without creating a
> mechanism that can be abused to unwrap proxies. For classes specifically,
> maybe an option can make that classes keep track of generated objects and
> throw if non-instance is passed in a method as |this| (...which is exactly
> the kind of things DOM Node tree manipulation methods will need)

Recall that it was a goal for classes to be a form of sugar over the
existing object model. That means the use of |this| within a method
specified using class syntax should really be no different from using
|this| outside of classes. Let's try to avoid making up special rules for
class instances.

The OP was about a proposal that auto-unwraps proxies specifically for
private symbol access. This decouples proxies and private symbols, but in a
potentially dangerous way (cf. the need to change membranes).
Auto-unwrapping a proxy without consulting the handler inherently breaks
abstraction boundaries.

Another alternative that crossed my mind, which may be as simple, and less

We could make proxies have their own private state, such that
proxy[privateSymbol] just accesses the proxy's private state (without
trapping!). That means there is no a priori relationship between
proxy[privateSymbol] and target[privateSymbol]. Basically this is also how
WeakMaps interact with proxies today (different identities, different

Under this proposal:
- private symbols are never leaked to proxies
- private symbol access is "reliable" (it never throws)
- private symbols don't pierce membranes
- proxies don't need facilities to interact with private symbols (the
whitelist and unknownPrivateSymbol trap)

What you lose is the ability to call a method that expects an object with
certain built-in state, and that will "just work" when passed a proxy for
an object with such state. Maybe this was a bad idea anyway.

Going back to the big discussion thread about proxying DOM objects, I
maintain that it's a bad idea to try to make existing APIs (that expect
objects of a very specific type) work with any random proxy, either by
interacting with it or by unwrapping it. The cleaner thing to do would be
to replace/wrap the API with one that also recognizes and accepts certain
proxies (still not just anyone's proxies).

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <>

More information about the es-discuss mailing list