Security Demands Simplicity (was: Private Slots)

Axel Rauschmayer axel at rauschma.de
Thu Jan 17 09:32:27 PST 2013


Can we separate of concerns?

1. I love symbols.

2. I also love the idea that you can mark properties as private, as invisible to the outside. Currently I prefix my properties with `_` to do so, but it’s an ugly namespace pollution.

3. But, for me and probably most applications, the privacy does not have to be bullet proof. For the rare cases where we need. bullet-proofing, weak maps might be enough.

4. Enumerability still seems like something that only exists because for for-in. Unfortunately, it can’t take up role #2, because so many things are already non-enumerable that are clearly public.

Does that mean that the current ES6 model could be simplified? For example: another property attribute `visible`, making properties invisible. Not sure where the invisibility matters: at an IDE level, when you do an expansion (e.g. type `myobj.`). Or should it also be hidden from all current iteration operations (Object.getOwnPropertyNames() etc.)? In either case, there would still be a way of iterating over all properties, making copying etc. straightforward.


On Jan 17, 2013, at 18:00 , "Mark S. Miller" <erights at google.com> wrote:

> First, I agree with David that security is important, both for
> security per se and for modularity in general. ES5 improved the
> language when it fixed the accidental leaks between the world of
> objects and scope-chain objects, like thrown functions. ES5/strict
> improved the language when it made functions really encapsulated,
> poisoned caller and arguments, and repaired the remaining violations
> of static scoping. ES6 modules and CommonJS/Node modules were born and
> remain encapsulated. I have not heard anyone suggesting any of these
> would be improved by introducing pliers for opening them against their
> will (except in a debugger, which is a different issue). Tons of code
> have been written in ES3. We still made the world a better place when
> we plugged its leaks.
> 
> I also agree with David that unique symbols are not an encapsulation
> mechanism, but rather, merely a mechanism to avoid namespace
> collisions.
> 
> As for Java's reflective breakage of "private",
> <http://www.nbcnews.com/technology/technolog/us-warns-java-software-security-concerns-escalate-1B7938755>.
> 
> 
> However, after the "Private Slots" thread, I spent a sleepless night
> chewing on getting rid of private symbols. I now think we should.
> Going back to my earlier
> 
> 
> On Wed, Jan 16, 2013 at 12:37 PM, Mark S. Miller <erights at google.com> wrote:
>> My position on private symbols.
>> 
>> My position on classes is and has always been that classes are worth
>> introducing into the language *only* if they give us, or can be used
>> with, an affordable means for true object encapsulation. Assuming
>> Allen is right about what actual implementors will do (which I find
>> plausible) then WeakMaps are not that means.
> 
> I still have this position on classes. But I no longer buy that
> pessimistic conclusion about WeakMaps. Consider how WeakMaps would be
> used by the expansion of classes-with-private. Just 'cause it's on the
> top of my head, below I use the old representation of one WeakMap per
> class providing access to a record of all the private state. For the
> same reason, I'll use the encapsulation of the Purse example without
> any of the numeric checks.
> 
> class Purse {
>    constructor(private balance) {
>    getBalance() { return balance; }
>    makePurse() { return Purse(0); }
>    deposit(amount, srcPurse) {
>        private(srcPurse).balance -= amount;
>        balance += amount;
>    }
> }
> 
> expansion
> 
> let Purse = (function() {
>    let amp = WeakMap();
>    function Purse(balance) {
>        amp.set(this, Object.seal({
>            get balance() { return balance; },
>            set balance(newBalance) { balance = newBalance; }
>        }));
>    }
>    Purse.prototype = {
>        getBalance: function() { return balance; },
>        makePurse: function() { return Purse(0); },
>        deposit: function(amount, srcPurse) {
>            amp.get(srcPurse).balance -= amount;
>        }
>    }
>    return Purse;
> })();
> 
> 
> Ignore the issues about whether we should use one WeakMap per class
> and a private record as above, or a WeakMap per private field name
> declaration.
> 
> Ignore the use of accessors so that private field names track
> variables. If we had instead stored the state in the private field and
> compiled getBalance to use the field, that doesn't affect the
> important issue.
> 
> 
> 
> **********************
> Notice that the lifetime of amp cannot be shorter than the lifetimes
> of the Point instances, since the instances retain amp, and these
> instances are the only objects ever stored as keys in amp.
> **********************
> 
> 
> 
> For this usage common pattern, the lifetime of the keys of amp cannot
> outlive the lifetime of amp.
> 
> Thus, no matter what the spec says, normatively or not, about expected
> storage costs, competitive pressures will drive JS engine implementors
> to make this efficient. The way to make this efficient is by the
> technique previously discussed -- hang the private state off of the
> object, not the weakmap. Use the weakmap only as an unforgeable token
> for naming and accessing this state. If we get rid of private symbols,
> we should expect this pattern of usage of WeakMap to have the same
> cost that private symbols would have had. We can help implementors
> achieve that by having this expansion call instead
> "WeakMap(USE_KEY_LIFETIME_HINT)" or whatever it is called. Then
> implementations would not have to recognize the pattern by other
> means.
> 
> Complexity is the enemy of security. We already have four
> encapsulation mechanisms in ES6 in addition to private symbols:
> 1) functions encapsulating lexical variables
> 2) WeakMaps
> 3) proxies encapsulating handlers and targets
> 4) modules encapsulating what they don't export.
> 
> With enough spec and engineering effort, any of these could be grown
> into a means for providing efficient class/object encapsulation. Of
> them, I think #2 is most plausible. Even is we find #2 does not work
> out, we should think about growing one of the other candidates as an
> alternative to private symbols. Security demands simplicity, and
> semantic simplicity is more important than implementation simplicity.
> 
> 
> 
> --
>    Cheers,
>    --MarkM
> _______________________________________________
> es-discuss mailing list
> es-discuss at mozilla.org
> https://mail.mozilla.org/listinfo/es-discuss
> 

-- 
Dr. Axel Rauschmayer
axel at rauschma.de

home: rauschma.de
twitter: twitter.com/rauschma
blog: 2ality.com

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.mozilla.org/pipermail/es-discuss/attachments/20130117/17bb8183/attachment-0001.html>


More information about the es-discuss mailing list