Security Demands Simplicity (was: Private Slots)

Allen Wirfs-Brock allen at
Mon Jan 21 11:14:53 PST 2013

On Jan 21, 2013, at 12:04 AM, David Bruant wrote:

> Le 21/01/2013 03:35, Allen Wirfs-Brock a écrit :
>> Also, I think some of the issues discussed in the thread have bearing on this discussion.  It is probably worth taking a second look.
> I think too that this thread revealed unclear stratification properties in built-in algorithms, but I'm not following how relates to this discussion.

In particular, look at the above threading starting here .  For internal method calls, the default behavior of Proxy is to forward to the target.  But for ES level method calls through the Proxy,  delegation is used. This can leads to inconsistent behavior between direct use of a target object and proxied use of that target, even if the proxy has no handler behavior.  

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. For example, if a built-in method requires a specific implementation level record structure, that method will fail unless it explicitly deals with the possibility it might be indirected through multiple proxies.

This is why we have the private symbol proxy issues we have been discussing.  Such a method, instead of directly accessing private symbol properties on on the instance it is operating upon is forced to re-delegate each access back through the proxy.

This also creates problems is you were using WeakMaps to represent encapsulated state:

import $$create ...  ;   //get the @@create symbol
let fooPrivate = new WeakMap;
export class Foo {
   doSomething)_ {
       let privateState = fooPrivate.get(this)        
       if (privateState == undefined) throw Error("invalid foo object");
       /* do something using the private state */
    [$$create] () {
         let obj = super[$$create]();  //allocate an ordinary instance
         fooPrivate.set(obj, {});  //set up a private slot for the new object
         return obj

let f = new Foo();
let pf = new Proxy(f, {});

f.doSomething();  //works fine
pf.doSomething();  //throws because pf is passed as the this value to doSomething and pf does not have an entry in fooPrivate.


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

More information about the es-discuss mailing list