Non-extensible WeakMaps

Brendan Eich brendan at mozilla.org
Mon Jan 23 10:21:05 PST 2012


We're not going to force everyone to use Map.new, so while this might be 
nice new API, it doesn't solve the problem of the prototype channel.

/be

> Andrea Giammarchi <mailto:andrea.giammarchi at gmail.com>
> January 23, 2012 10:13 AM
> for what it's worth it ...
>
> Object.defineProperty(Object.prototype, "new", {value: function 
> (descriptor) {
> return Object.create(typeof this == "function" ?
> this.prototype :
> this,
> descriptor || {}
> );
> }});
>
> Map.new() and Math.new() should both work
>
> my 2 cents
>
>
> _______________________________________________
> es-discuss mailing list
> es-discuss at mozilla.org
> https://mail.mozilla.org/listinfo/es-discuss
> Brendan Eich <mailto:brendan at mozilla.org>
> January 23, 2012 8:25 AM
>> David Bruant <mailto:bruant.d at gmail.com>
>> January 22, 2012 12:54 PM
>> I'm not sure to understand what you're calling "/the/ key". 
>> WeakMap.prototype, being itself a weakmap, does provide a covert 
>> channel (since everyone has access to the same primordial objects 
>> identities). Of course, it can be repaired [1], but it's quite 
>> unfortunate to have to "repair" a feature that isn't part of a 
>> standard yet, isn't it?
>
> Yes, you're right -- the prototypes require special handling for some 
> of these classes. We've talked about this at past meetings. It's 
> unfortunate that in JS, a prototype is not instanceof the objects of 
> its kind.
>
> There is a tension between making prototypes be blank Object instances 
> and making them as if they were the first of their kind. For the 
> built-ins, we did the latter up till ES3, where RegExp.prototype was 
> spec'ed as Object. No implementation followed that part of ES3, and 
> ES5 matched reality.
>
> We would like a principled way for built-in constructors that have 
> such covert channel hazards to opt out of their prototype being of 
> their kind.
>
>>> For Maps and Sets, which support enumeration, the threa[t] model is
>>> different.
>> Allowing any type to be a key also changes the threat model, because it
>> means that prior arrangement can be enough to communicate.
>
> True but it's only with such arrangement, which would be a different 
> kind of bug from any in the case where a key could be forged. In the 
> forged key case, there's no defense.
>
>> However, besides the {WeakMap|Map|Set}.prototype, I do not see anything
>> that cannot be controlled with a revocable caretaker.
>
> Right, and these are needed in general in same-frame mashups anyway 
> (if I understand correctly). Mark is Jedi master here, he should weigh 
> in.
>
> /be
>>
> David Bruant <mailto:bruant.d at gmail.com>
> January 22, 2012 12:54 PM
> Le 22/01/2012 21:11, Brendan Eich a écrit :
>>> Herby Vojčík<mailto:herby at mailbox.sk>
>>> January 22, 2012 11:42 AM
>>> David Bruant wrote:
>>>> I agree that Object.preventExtensions is defined as preventing addition
>>>> of new properties. Likewise, Object.freeze and Object.seal only act on
>>>> object properties (extended to private properties?).
>> No, we agreed the property visiting under freeze and seal does *not*
>> affect private-object-named properties.
> Ok.
>
>>>> But the broader problem they are addressing is reducing the mutability
>>>> of objects. WeakMaps, maps and sets bring a new form of mutability
>>>> which
>>>> cannot be implemented in the form of private properties (I think at
>>>> least). So the question is:
>>>>
>>>> Should Object.preventExtensions be extended to reduce WeakMaps, Maps
>>>> and
>>>> Sets mutability? Likewise for Object.seal|freeze?
>>> It would be special case. I'd say no.
>> I agree so far as this goes.
>>
>> Mark has thought deeply about this topic, with the use-case of
>> preventing extensions being the closing of covert or side channels in
>> JS objects. For private names and weak maps, there is no channel to
>> close via preventExtensions, since the attacker by definition doesn't
>> have the key.
> I'm not sure to understand what you're calling "/the/ key".
> WeakMap.prototype, being itself a weakmap, does provide a covert channel
> (since everyone has access to the same primordial objects identities).
> Of course, it can be repaired [1], but it's quite unfortunate to have to
> "repair" a feature that isn't part of a standard yet, isn't it?
>
> I'm seeing that it is suggested [2] that WeakMap.prototype.set(k,v) and
> WeakMap.prototype.delete(k) throw a TypeError (instead of trying to
> mutate WeakMap.prototype). Instead of WeakMap.prototype being a
> non-mutable weakmap, what about it being not a weakmap at all? (and
> throw for .has and .get as well)
>
>> For Maps and Sets, which support enumeration, the thread model is
>> different.
> Allowing any type to be a key also changes the threat model, because it
> means that prior arrangement can be enough to communicate.
>
> However, besides the {WeakMap|Map|Set}.prototype, I do not see anything
> that cannot be controlled with a revocable caretaker.
>
> David
>
> [1]
> http://code.google.com/p/es-lab/source/browse/trunk/src/ses/initSES.js#2237
> [2] https://bugzilla.mozilla.org/show_bug.cgi?id=656828
>
> Brendan Eich <mailto:brendan at mozilla.org>
> January 22, 2012 12:11 PM
>> Herby Vojčík <mailto:herby at mailbox.sk>
>> January 22, 2012 11:42 AM
>> David Bruant wrote:
>>> I agree that Object.preventExtensions is defined as preventing addition
>>> of new properties. Likewise, Object.freeze and Object.seal only act on
>>> object properties (extended to private properties?).
>
> No, we agreed the property visiting under freeze and seal does *not* 
> affect private-object-named properties.
>
>>> But the broader problem they are addressing is reducing the mutability
>>> of objects. WeakMaps, maps and sets bring a new form of mutability 
>>> which
>>> cannot be implemented in the form of private properties (I think at
>>> least). So the question is:
>>>
>>> Should Object.preventExtensions be extended to reduce WeakMaps, Maps 
>>> and
>>> Sets mutability? Likewise for Object.seal|freeze?
>>
>> It would be special case. I'd say no.
>
> I agree so far as this goes.
>
> Mark has thought deeply about this topic, with the use-case of 
> preventing extensions being the closing of covert or side channels in 
> JS objects. For private names and weak maps, there is no channel to 
> close via preventExtensions, since the attacker by definition doesn't 
> have the key. For Maps and Sets, which support enumeration, the thread 
> model is different.
>
> /be
> Herby Vojčík <mailto:herby at mailbox.sk>
> January 22, 2012 11:42 AM
> David Bruant wrote:
>> I agree that Object.preventExtensions is defined as preventing addition
>> of new properties. Likewise, Object.freeze and Object.seal only act on
>> object properties (extended to private properties?).
>> But the broader problem they are addressing is reducing the mutability
>> of objects. WeakMaps, maps and sets bring a new form of mutability which
>> cannot be implemented in the form of private properties (I think at
>> least). So the question is:
>>
>> Should Object.preventExtensions be extended to reduce WeakMaps, Maps and
>> Sets mutability? Likewise for Object.seal|freeze?
>
> It would be special case. I'd say no.
> Collections should proabably get their own API for this, analogic to 
> Object.preventExtension|seal|freeze.
>
> Where to put it, is the question. It should probably be callable like 
> Map.seal(aMap), Array.freeze(anArray) etc. If a collection hierarchy 
> has common ancestor, constructor function can inherit in parallel with 
> prototypes, so it may in fact reside in that(ose) common base classes.
>
>> David
>
> Herby
>
> P.S.: Array.xxx version should be able to work only on indexed 
> elements, not or other properties (it is Object.xxx's work). Of course 
> them same for Map etc., but there it is natural.
> _______________________________________________
> es-discuss mailing list
> es-discuss at mozilla.org
> https://mail.mozilla.org/listinfo/es-discuss
>


More information about the es-discuss mailing list