Le 11/01/2013 06:46, Nathan Wall a écrit :
David Bruant wrote:
For the long term, I expected DOM objects could be proxified.
Boris convinced me otherwise for DOM Nodes at least.
Are you so convinced that the `unknownPrivateSymbol` trap is necessary?
I would think so, for instance, when one wants to revoke access to a given object, one needs to be able to throw and for that a trap must be called also when the private symbol is unknown, this is a defensive scenario too.
Imagine the following scenario:
Untrusted code A is given access to a graph of objects through a membrane. Likewise for B with a different membrane. If both A and B have access to the same target, each through a proxy of their respective membrane. Now, you want to revoke access to all their membrane (including the shared target) to both A and B, because you don't want A and B to be able to communicate anymore.

If there is no unknownPrivateSymbol trap, A and B can continue to communicate through the private property on the shared target (through their respective proxy to it) and you have no way to prevent that. Even freezing the object wouldn't work apparently.

It's been decided early that a Proxy.isProxy method should be avoided,
because proxies should be indetectable from the objects they try to
emulate from the ECMAScript perspective
I thought part of the goal in ES6 was striving to make the DOM emulable (dare I 
say implementable?) in pure ES.
I'm working for this to happen and it seems to be shared by TC39 (which I'm not part of)

If that's the case, the inability of DOM objects to be proxied sounds like a 
big deal.

(A) If a proxy is allowed to have a DOM node as its target, but 
`element.appendChild(proxiedNode)` throws, then you can detect if an object is 
a proxied DOM node based on whether it throws when you call `appendChild`:

     function isNodeProxy(node) {
         try {
             return node instanceof Node &&
                 document.body.appendChild(node) &&
                 !!document.body.removeChild(node);
         } catch(x) {
             return false;
         }
     }
Leaking the information that the node is actually a proxy is due to a DOM API issue (which is way way too late to fix obviously). If you want proxied node to go in the tree, you'll need to find an answer to the issue Boris Zbarsky brought up about selector matching [1]. I've given up [2], but I'm curious to know if there is a decent solution.

You're however not saying how this leak may be a problem for self-hosting (emulating in pure ES) the DOM. I'm addressing that after answering to your B.

(B) If a proxy isn't allowed to have a DOM node as its target and ES objects 
have no way to refuse being proxied, then the DOM is allowed to do something ES 
can't, widening the gap.
I'm in favor of allowing nodes to be used as proxy targets and having the Reflect API [3] work on them as expected, yet forbidding their use in DOM tree manipulation methods.


Assuming nodes can be proxied and proxied node are refused to be appended. How can this be implemented in pure ES? All non-proxy nodes are created internally (via HTML parsing) or through document.createElement (are there others?), so, the DOM can keep a list of the exact objects belonging to the document and refuse appending *any* other object (discriminated with object identity) including proxied nodes.

A consistent approach might be having some way for an ES object to refuse being 
proxied, but It still sounds to me like the real problem is the 
`unknownPrivateSymbol` trap.

If you take this trap away, wouldn't that let DOM objects be proxied? If you 
leave this trap there, library authors who want the same level of integrity as 
the DOM developers want will avoid symbols and try to come up with a WeakMap 
solution (which will require a bit of legging to work with inheritance I now 
realize, but I think it can be done).  Who knows, if a good enough WeakMap 
micro-library is worked out that can come close to simulating symbols without 
the `unknownPrivateSymbol` problem, private symbols may even become an 
anti-pattern. Or security-minded developers might just retreat back into 
closure-classes. Are there good enough reasons to leave the 
`unknownPrivateSymbol` trap at such an expense?
I set up a use case above. If you have an alternative, I'm listening.

What does `unknownPrivateSymbol` gain? Someone can always write around it with 
WeakMaps and closures.
In the above setup, if A and B shared a weakmap, the weakmap had to go through the membrane before being shared and at least one of the 2 has a membraned version, so its access will be cut when the membrane is revoked.

Thinking a bit more about how A and B can share things, I'm realizing that anytime they want to share a private symbol, they have to do it through a "capturable" channel (set trap value argument, etc.). So if A and B are in touch, the membrane could capture all private symbols going from one side to the other and add it to the membrane whitelist. This way, anytime there is a communication attempt via private symbols, the private symbol is known and the non-unknownPrivateSymbol trap is called. In theory, it makes the unknownPrivateSymbol not absolutely necessary for this use case. In practice, to capture all communication, anytime the membranes intercept a new symbol, it needs to make sure it wasn't used on any other object previously shared between both parties and that means traversing entire graphs of objects which may be an enormous amount of work degrading performance.
I'm also not a big fan of retroffiting control afterwards.

One thing I have read is it could help in the case of a read-only proxy which would throw 
anytime `unknownPrivateSymbol` is called with a "set" invocation, but that 
doesn't really ensure an object is any more read-only than without `unknownPrivateSymbol` 
if the object just avoids symbols.
I think I suggested that to promote the idea of passing the original operation as a second argument of the unknownPrivateSymbol trap. It's not been agreed on. One main use case for proxies is using them as intermediary. If there is a circumstance (like private symbol properties) where the proxy can be entirely bypassed, then, that use case fails to be fulfilled.

David

[1] https://mail.mozilla.org/pipermail/es-discuss/2013-January/027952.html
[2] https://mail.mozilla.org/pipermail/es-discuss/2013-January/027955.html
[3] http://wiki.ecmascript.org/doku.php?id=harmony:reflect_api
_______________________________________________
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss

Reply via email to