I've been following the threads on WeakMap.prototype.clear with interest, and I think I may have an argument that should make the existence of WeakMap.prototype.clear irrelevant from an ocap security perspective.<div><br>
</div><div>It was already previously suggested in this thread that the ocap thing to do would be to prevent access from untrusted code to your WeakMap instance in the first place.</div><div><br></div><div>I think the suggestion that WeakMaps could be shared freely safely if only they didn't have a .clear() method is wrong.</div>
<div><br></div><div>Consider for a moment that WeakMaps don't have a .clear() method so you know no one can get at your values without having access to the corresponding keys. So you share your WeakMap freely with untrusted code. This still leaves you open to another attack. Before I can describe the attack, I think it's useful if people have some understanding of what the "rights amplification" pattern actually is.</div>
<div><br></div><div>The "rights amplification" pattern that MarkM previously referred to is often used to convert an opaque, untrusted object reference into a value your code can trust.</div><div><br></div><div>
In my trusted code, I can write:</div><div><br></div><div>token = Object.freeze({});</div><div>myWeakMap.set(token, myTrustedObject);</div><div>return token;</div><div><br></div><div>I now pass around the token to code in the wild.</div>
<div><br></div><div>The token by itself is useless. It's only useful if someone later passes it back to my code:</div><div><br></div><div>function doSomethingWith(token) {</div><div>  // token could be anything, I don't trust it</div>
<div>  var trustedObj = myWeakMap.get(token);</div><div>  // if trustedObj is not undefined, the token was legitimate</div><div>}</div><div><br></div><div><br></div><div>This pattern really hinges on the WeakMap being properly encapsulated. If it isn't, an attacker could just mint his own tokens, add them to the WeakMap, and then fool my trusted code into thinking that the token is legitimate.</div>
<div><br></div><div>In other words: if one wants to share a WeakMap with untrusted code, one must already wrap it such that access to the "set" method is prohibited as well. In this regard, also having to remove .clear() is a marginal extra cost, compared to the more general utility of this method when using WeakMaps for caches rather than for rights amplification.</div>
<div><br></div><div>Cheers,</div><div>Tom</div><div><div><br><div class="gmail_quote">2013/1/22 David Bruant <span dir="ltr"><<a href="mailto:bruant.d@gmail.com" target="_blank">bruant.d@gmail.com</a>></span><br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
Le 22/01/2013 15:59, Jason Orendorff a écrit :<br>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div class="im">
A) Are there more WeakMap applications that will want .clear() or applications that will want .clear() not to exist? Offhand I would bet on the former, by a landslide, but if you think otherwise, or if there's some other reason to privilege .clear() not existing, let's talk about that.<br>

<br></div>
(...)<div class="im"><br>
<br>
Having said all that, I bet we could hack around the worst-case GC performance. It'll be a pain, but GC is like that sometimes. This decision should hinge on what provides the best API for developers. I think we mainly disagree on what developers want, which is a great thing to talk about. Let's talk about that.<br>

</div></blockquote>
I agree use case dominant is a crucially important answer. To date, I honestly don't know which case of want-clear and don't-want-clear would be dominant. I agree Allen showed a compelling use case but I can't judge how important it is. In my experience, I've not had the need for a .clear yet. I know that in some occurences, my code relies on the weakmap not being emptied, but I've kept the weakmap well-encapsulated in these cases so this experience is not that relevant (because intrusive .clear can't happen).<br>

<br>
I've written a whole paragraph which is the most factual I can say on the topic, but doesn't help the debate much.<br>
<br>
When it comes to feelings, I prefer prudence by default. I'd like to say a few words about that. I understand that features shouldn't be seen only with ocaps eyes, but I'd like to take a moment to describe what I care about when it comes to ocaps and what we call "security".<br>

Node.js is an interesting ecosystem. There are a lot of modules, it's not unusual to use 10-20 modules in a project which can make 100+ modules when counting recursively. Because it costs a lot of time, it's not possible to rewrite everything, it's not possible to contribute the necessary test coverage to modules and it's not possible to do careful security reviews of all used modules (and updates!).<br>

However, it's possible to apply POLA (Principle Of Least Authority), that is give to each module the information and capabilities it needs to do its job and no more. If WeakMap.prototype.clear gets natively in the language, it means *all* modules can have an irrevocable right to flush any weakmap I hand them.<br>

It's the same sort of problem than if a "free" operator was brought to JavaScript (in advance, I agree that the .clear is more acceptable) as suggested once [1] (almost ironically by Node's lead?). Suddenly, a module could free objects you hand out to them. A module thinks it's freeing one of it's own objects but actually frees one of yours because of a bug? Too bad, you'll be throwing a TypeError very soon and who knows in which state it will leave your application.<br>

Dave Herman made an equivalent case about coroutines [2]. It provides abusive authority: you call a module-imported function and for whatever good or bad reason, it can suddenly stop the stack. It makes your code harder to reason about because when you wrote the code, you probably expected the function call to return (or throw).<br>

<br>
Back to weakmaps, the issue here is not technical, but... cultural I would say. I can decide to encapsulate my weakmap in a WeakMapWithoutClear, but doing so, I cut myself from modules which take .clear for granted. A module does rely on WeakMap clearbility? It will hand me the weakmap I'm supposed to use and I know in advance anything can happen, because I didn't create this object.<br>

If weakmaps don't have a clear, modules using language weakmaps won't take it for granted and you can be fearless about sharing your weakmap... very much like you can be  hand objects today without the fear of them being free'd by mistake or malice using a free operator.<br>

<br>
Since I'm on the topic of language-based abusive authority, I've come across a case where a logging library would throw at my face [3] anytime it would have to log about an object with a cycle in it [4]. Logging libraries are really not the one you'd expect to throw an error so we didn't wrap the call in a try-catch. So logging some objects would make the application crash.<br>

I have come to think that error-throwing with stack-unwinding is an abusive authority. Especially given that try-catch is an opt-in.<br>
I understand now that silently swallowing errors is not a good idea and the need to report errors in a different channel than return value, but I don't think stack-unwinding is a good default for that. Promises show an interesting model; to keep in mind for another language maybe.<br>

<br>
The point I tried to make here is that POLA allows to build applications using untrusted modules without fearing them and that's really an excellent property, because we use constantly huge amounts code we don't necessarily trust or have the time to review or test besides what we test during the development period.<br>

<br>
WeakMap.prototype.clear is at a different scale of "danger" and abusive authority than a hypothetical free operator or coroutine or abusive stack-unwinding, but it's an issue of the same family.<br>
Whether the smaller scale of danger makes it acceptable is a good question. I would answer "no" by default, but I can understand if others say "yes" for this one. To be balanced with advantages that native WeakMap.prototype.clear provide which are yet to be accurately determined.<br>

<br>
David<br>
<br>
[1] <a href="https://mail.mozilla.org/pipermail/es-discuss/2012-October/026007.html" target="_blank">https://mail.mozilla.org/<u></u>pipermail/es-discuss/2012-<u></u>October/026007.html</a><br>
[2] <a href="http://calculist.org/blog/2011/12/14/why-coroutines-wont-work-on-the-web/" target="_blank">http://calculist.org/blog/<u></u>2011/12/14/why-coroutines-<u></u>wont-work-on-the-web/</a><br>
[3] <a href="https://github.com/flatiron/winston/issues/151" target="_blank">https://github.com/flatiron/<u></u>winston/issues/151</a><br>
[4] <a href="https://github.com/flatiron/winston/issues/100" target="_blank">https://github.com/flatiron/<u></u>winston/issues/100</a><div class="HOEnZb"><div class="h5"><br>
______________________________<u></u>_________________<br>
es-discuss mailing list<br>
<a href="mailto:es-discuss@mozilla.org" target="_blank">es-discuss@mozilla.org</a><br>
<a href="https://mail.mozilla.org/listinfo/es-discuss" target="_blank">https://mail.mozilla.org/<u></u>listinfo/es-discuss</a><br>
</div></div></blockquote></div><br></div></div>