WeakMap API questions?

Mark S. Miller erights at google.com
Thu Sep 2 09:14:31 PDT 2010

On Thu, Sep 2, 2010 at 8:05 AM, Bradley Meck <bradley.meck at gmail.com> wrote:

> I would like to agree that .keys would expose some of the internal workings
> of the GC. This is true, but the solution to that could be to remove .keys()
> off the individual WeakMap for secure operations,

Remove off of which individual WeakMap? In the example attack I posted, the
WeakMap used by the attacker (c.js) is created and used only by the
attacker. The defender code interested in secure operation (a.js) does not
create or use any WeakMaps, and shouldn't need to worry about them in order
to stay secure. The alternative -- that every time we add a new feature to
the language we add to the (already almost impossible) burden that defenders
need to worry about -- is, well, at least in the web world it is traditional
;). In any case, even if we do add this to a.js's burden, it's not clear
what it could do about this threat anyway. If we added .getKeys() to
WeakMaps, code out of the defenders control could not be stopped from
creating new WeakMaps and using them to spy on GC liveness that was none of
its business.

> however in some situations where a WeakMap is sandboxed within a closure or
> such, having .keys allows for sharing private variables between objects
> discretely without exposing them to the public eye (similair to the friendly
> idea in c++). Lets take a look at a use case of weak maps to hold private
> information:
> (function(){
> var hiddenMap = new WeakMap()
> //constructor function
> Foo = function Foo() {
>   var private = {friends:[]}
>   hiddenMap.set(this,private)
> }
> Foo.prototype.verifyAgainst = function(otherFoo) {
>   var otherFoo_private = hiddenMap.get(otherFoo)
>   var thisFoo_private = hiddenMap.get(this)
>   if(otherFoo_private.friends.indexOf(this)!==-1&&thisFoo_private.friends.indexOf(otherFoo)!==-1)
> {
>     //do something only friends can do
>   }
> }
> Foo.prototype.extend = function(subconstructorFactory) {
>   return subconstructorFactory(hiddenMap)
> }
> })()
> ...
> known to be secure code
> ...
> Foo.prototype.extend = null
> ...
> non-secure code
> ...

In the example above, how does anything get into any friends lists? I could
guess a plausible answer, but given the subtleties of the issues, I'll just
wait for you to clarify. Thanks.

> Now say we extend Foo with Bar (inside the secure code area), and Bar wants
> to request access to all of the Foos in order to track which Foos are
> friends with each other on both ends.

Why would Bar want that? There are all sorts of things that one might want,
that we used to have, and that are occasionally useful, like reading
arbitrary addresses of memory, that we have learned to deny ourselves
because they're too dangerous. Note that my example here is only reading --
which threatens only confidentiality or encapsulation of information, not
integrity. I agree that .getKeys() poses no integrity threat.

One well motivated use case for such encapsulation-violating magic powers is
debuggers. Indeed, debuggers can already do all sorts of magic things to the
computation being debugged that are outside the powers of unprivileged
programs within the language, such as peeking into closures. In adding
WeakMaps to JS implementations, it does make perfect sense to add a
.getKeys() operation to the debugger's eye view of WeakMaps. Likewise with
other potentially even more powerful and dangerous instrumentation or
intervention in the local GC.

> How will we be able to get a list of all the Foos in existence without
> leaking right now? The only possibilities I see are to not allow these sort
> of operations or to leak. On the level of use, it seems to me like a strict
> mode case vs a normal mode case unless we gain a collector callback.

I don't get it. How would you hang this distinction on strict mode vs
non-strict mode.

(Btw, **please** don't call non-strict mode "normal".)

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.mozilla.org/pipermail/es-discuss/attachments/20100902/e6836f6a/attachment.html>

More information about the es-discuss mailing list