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