Why not private symbols?

Brandon Benvie bbenvie at mozilla.com
Fri Aug 2 13:21:23 PDT 2013


On 8/2/2013 1:15 PM, Domenic Denicola wrote:
> From: Brandon Benvie [bbenvie at mozilla.com]
>
>> That would leak the Symbol to the Proxy and then private Symbols wouldn't carry a guarantee of security. That's the only difference between private Symbols and unique Symbols.
> Right, I thought about that, but I am still not quite clear on what the attack is here. From an ocap sense, it feels like you're handing off the private symbol to the proxy, which is just like exporting it from your module or passing it to a function. Why should the proxy not have access to something that you gave it?
>
> The attacks I normally consider public symbols vulnerable to are of the form:
>
> ```js
> module "foo" {
>    const public = Symbol();
>
>    export default {
>      [public]: 10
>    };
> }
>
> module "bar" {
>    import foo from "foo";
>    // Nobody gave me access to the `public` symbol, but I can still do:
>    const public = Object.getOwnPropertyKeys(foo)[0];
>    // Now I can modify the exported object:
>    foo[public] = 20;
> }
> ```
>
> What would the similar attack code look like for a proxy?

The problem is methods acting on a Proxy |this| value could leak the Symbol:


```js
module "foo" {
   const secret = Symbol();
   export default class Foo {
     constructor(){
       this[secret] = Math.random();
     }
     increment(){
       this[secret]++;
     }
   }
}

module "bar" {
   import Foo from "foo";

   var secret;

   new Proxy(new Foo(), {
     get(target, key, receiver){
       if (typeof key === 'symbol') {
         secret = key;
       }
       return Reflect.get(target, key, receiver);
     }
   }).increment();

   console.log(secret); // should be the Symbol here
}
```


More information about the es-discuss mailing list