Alternative proposal to privateName.public

David Bruant bruant.d at gmail.com
Sat Dec 17 05:24:02 PST 2011


Hi,

Here is a proposal related to the discussion we've had in the other
thread. Gist: https://gist.github.com/1490167

# Introduction

We've seen in [the thread "Are Private name and Weak Map the same
feature? and the Assoc
API"](https://mail.mozilla.org/pipermail/es-discuss/2011-December/018875.html)
that .public was here to prevent proxies from having access to a private
name. This constructs results in a bigger efforts to use private names
in coordination with proxies (need to access the public part and a map
to retrieve the private name with the remaining danger of sharing the
map with the wrong entities).

[Sam Tobin-Hochstadt gave an
example](https://mail.mozilla.org/pipermail/es-discuss/2011-December/018901.html)
of a simple program we may not expect to leak a private name but would
if private names passed through proxies and the program was used with a
malicious proxy.
I answered that we should consider changing the way we write program and
I admit that I am myself a bit annoyed by this statement.

So here is a proposal where I think I can make both parties (those who
don't want to write complicated programs to protect their private names
and those who don't want to write complicated programs to make private
names and proxies work together) happy.

# Proposal

What about a 'trapped' boolean in the private name constructor?

It would work this way:

`````JavaScript
var n = new Name(false); // don't trap when used is a proxy
var p = new Proxy({}, maliciousHandler);

p[n] = 21; // the set trap is NOT called!
var v = p[n]; // the get trap is NOT called and v === 21
`````

Basically, when the private name is created with the 'trapped' boolean
to false, the proxy becomes oblivious to being called with these private
names.

`````JavaScript
var n = new Name(true); // trap when used on a proxy
var p = new Proxy({}, {
    get:function(target, name, receiver){
        console.log(name === n);
        return target[name];
    },
    set:function(target, name, val, receiver){
        console.log(name === n);
        target[name] = val;
    }
});

p[n] = 21; // the set trap is called and logs 'true'
var v = p[n]; // the get trap is called, logs 'true' and v === 21
`````

The name passed to the traps is the actual private name.

In the case exposed by Sam, using an untrapped name will do the trick,
in my cases, using trapped names will do the trick as well.
If someone wants some proxies (and by "proxies" I mean "untrusted third
party") to have access to a secret and some not, then, i think it's fair
to ask this person to have several secrets and dictionary and arbitrary
complicated constructs to achieve her goal.

If as Sam suggested, most cases don't need proxies to have access to an
information, let the default value of 'trapped' be 'false'.

I expect the following response: "but then the proxy does not reify the
operation made on untrapped private names". It is true and it is true
with the current proposal as well. Currently, maybe that the proxy traps
something but it's using an altered information (which I'm not sure can
really be considered as a true reification). At the end of the day, I
don't think there is a feature loss in not calling a function or calling
it with a virtually useless information.
What I'm proposing is to make more explicit (a boolean in the private
name constructor) whether or not we want a proxy to do something useful
with a name.

Is it a good compromise?

David


More information about the es-discuss mailing list