Security Demands Simplicity (was: Private Slots)

Allen Wirfs-Brock allen at wirfs-brock.com
Mon Jan 21 21:27:19 PST 2013


(This message seems like a reasonable place  to jump back into this thread.  But, I'm not particularly picking on Tom here...)


On Jan 21, 2013, at 1:31 PM, Tom Van Cutsem wrote:

> 2013/1/21 Kevin Smith <khs4473 at gmail.com>
> 
> 
> A root  problem is that on method invocations through a proxy methods of the target object are invoked with the proxy, rather than the target, as the this value.  This means that any assumption the methods have about valid this values are broken.
> 
I'll +1 myself here.

> I believe this is correct.  It is a separate proxy issue not directly related to WeakMap/private symbol debate.
> 
Actually, I think it is closely related.  Private state state access (and branding) mechanism don't work if you don't have the right this value or if the private state access doesn't automatically forward through through a proxy this to the target this.. 

> Indeed. But in Javascript, methods shouldn't (in general) make any assumptions about their |this| values. The |this| value can be any random object. It's just the zeroth parameter to a function. That's why in traits.js (which was designed for high-integrity abstractions) we decided to .bind() all methods so the |this| value could be relied upon.

I understand and largely agree with the spirit of this comment, but in fact Javascript methods make all sort of assumptions about their this value.  Every time you invoke a method property or access a state property through this you are making assumptions. Every time you check the identify of this you are making assumptions.  Every time you pass this to another function you are making assumptions.  Many times the assumptions aren't verified (and I think that is typically a good design choice) but if they are violated, the program will misbehave.

Sometimes, methods preflight check that the this value is the "right kind" of object.  Many of the built-in methods do this, presumably so they can take advantage of optimized native layout.  If those checks aren't made an implementation could have memory corruption bugs.

Passing the proxy rather than the target as the this value creates problems because the mechanism that are used to verify the assumptions or or the assumptions thenselves depend upon either object identify (for example looking up the this value in a WeakMap based brand registry) or direct access to target object state (most of the built-ins).

The current Proxy design side-steps these issues in some special cases. For example [[Prototype]] access is a special MOP call that always reaches into the target. But, as far as I can tell there isn't a general solution to this problem in the current Proxy design.  Certainly it isn't clear how the built-ins are supposed to be specified so that they work when handed a proxy as their this value. 

We can probably fix the built-ins with some ad hoc language about them automatically resolving proxies to the target as the this value. Or perhaps we could expand the internal MOP api  to include a resolve proxy to target operation.  

Using private symbols for all of these cases, including the built-ins also seems like an alternative that may work. 

Allen



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


More information about the es-discuss mailing list