Sept 19 TC39 Meeting Notes

Rick Waldron waldron.rick at gmail.com
Fri Sep 28 08:31:03 PDT 2012


Ugh, sorry about that. I had a momentary brain melt and forgot to unformat before sending  

-Rick


On Friday, September 28, 2012 at 4:20 AM, David Bruant wrote:

> Thanks Rick for the notes (and everyone who contributed, I see several colors)
>  
> Le 28/09/2012 03:00, Rick Waldron a écrit :
> > # Proxy  
> > (Presented by Tom Van Cutsem, Free University of Brussels)
> >  
> > ## Revokable Proxies   
> >  
> > (...)  
> >  
> > Question as to whether we really need two kinds of proxies.  
> > BE: yes, non-revokable proxies have less trap overhead (no null-check)
> >  
>  
> I think it's possible to implement both without any overhead.
> TVC suggested below that a revoked proxy is equivalent to a proxy with all traps unconditionally throwing; well, a proxy, when revoke could drop its target and change its handler on revokation.
>  
> A proxy can be modelled as {target, handler}. Both handler and target are set at proxy creation and can't be changed arbitrarily by JS code. We can model revocation as a capability that enables to change in one operation both target to null and handler to a built-in handler which throws on any operation. (it remains impossible to change target and handler arbitrarily in JS code)
> Modeled and implemented this way, there is no need for a null check. When trapping, the revoked target (null) is passed to the handler trap, which doesn't care since it throws regardless of the target value.
> In that model, both type of proxies are just the same type and are as efficient. No need for a null check before trapping. Just trap with the current value and only provide to JS-land the capability to change the target (only to a null value) through revokation.
>  
> > Discussion about whether revokable proxies introduce new ways for interceptable operations to behave.  
> >  
> > WH: Not sure about this as a feature, w/r to future hostility…  
> > -  eg. if "===" would trap to the handler how does this work with that?
> >  
> > MM: trapping "===" would be a significant change on its own, independent of revokable proxies  
> >  
> > TVC: The only type test that is affected is typeof: once the proxy is revoked, it drops references to its target and its handler, so it can no longer forward the typeof test to its target  
> >  
> > BE: It remembers "function" or "object"  
> > TVC: right
> >  
>  
> Arguably, a revoked proxy could throw on === or typeof too.
> It's already allowed to arbitrarily throw on [[Get]], [[Put]], 'in', for-in/of loops, Object.getPrototypeOf, etc. It's not that big of a stretch to throw on typeof or === even though these aren't trappable.
> Unconditionally trapping on any operation on the object is future-proof.
>  
> > (...)  
> > WH: So, a frozen object can "unfreeze" itself?
> >  
> > MM: No  
> >  
> > WH: An object that is frozen can later refuse that its frozen  
> > Concern about trapping isFrozen etc.: these tests are no longer stable.
> > MM: but are still fail-stop. The integrity guarantee (i.e. that it always returns a correct answer) is more important than the availability guarantee (i.e. that it always returns an answer)
> >  
>  
> I agree.
> If it's proven that the availability guarantee really matters in some cases, I think a lot of things need to be re-designed in the proxy API. How much does it matter?
>  
> > Alternative to trapping isFrozen etc.: cache stable outcome of certain operations in the proxy, and afterwards no longer trap.  
> >  
> > STH: After the first time isfrozen is true, mark to no longer call.  
> >  
> > AWB: would preclude valid use cases that e.g. want to log all requested isFrozen operations. I agree. Proxies are a tool a virtualization. Restricting the way proxies proxy through invariant checking is one thing, but preventing from proxying seems to be a step too far in my opinion.
>  
> (...)  
> > **Conclusion/Resolution**
> > - we want revocable proxies
> > - further discussion is needed on revoking frozen objects, either via revocable proxies or via traps
> >  
>  
>     var t = Object.freeze({s: a300MbString});
>     var {revoke, proxy} = Proxy.revokable(t, {});
>     revoke();  
>     proxy.s; // ?
>  
> If the result is the long string because t is frozen, then it defeats the purpose of why revokation is being introduced in the first place (see TVC's problem description).
>  
>  
> >  
> > ## Proxy and Private Names  
> >  
> > TVC: We don't want Proxy to inadvertently leak private name properties.  
> >  
> > In Redmond, we discussed that we would seperate string properties and private name properties into separate traps.  
> >  
> > Later determined that this would become cumbersome.  
> >  
> > Proposing to add a third argument to the Proxy constructor: a "whitelist" of private name properties that are allowed to be trapped.  
> >  
> > WH: unique vs private names?  
> > STH: The primary purpose of Names is to avoid name clash and non-forgeable. Uniques should be reflected, private: not.
> >  
> > WH: What makes them non-forgeable  
> >  
> > STH: They are objects I think it was Tom who suggested in a post that symbols (I'll do my best to use the new terminology!) are more non-forgeable strings than non-forgeable objects. Symbols should not be proxyable. Their only important attribute is their identity, so proxying them would be absurd.
> I think it should be considered to have symboles typeof to be "string" instead of "object", or maybe something completely new, but for sure, they are not objects.
>  
> >  
> > DH: And are as non-forgeable as objects,   
> >  
> > WH: Why do we need both? Unique, Private?  
> >  
> > AWB: They are both useful  
> >  
> > STH: Unique names give you actual unforgeability  
> >  
> > MM: as opposed to the "unguessability" of randomly chosen strings  
> >  
> > DH: About the whitelist, instead of _requiring_ a WeakSet,  can it be anything that can be passed to a WeakSet, like an Array?  
> >  
> > MM: Should probably use a WeakMap… Why so? I agree on the "weak", but it seems we want the whitelist to be a set. The only operation on the whitelist internally is "has". It's useful if JS code can "add" and "remove" elements. It looks like the contract of a set, doesn't it?
>  
> >  
> > EA: An object that has a method that takes the public name string and returns the private name object, if you have access to that, you can extract the private data.   
> >  
> > STH: Erik is right, but it a  
> >  
> > MM: if we don't drop the .public property, don't need the whitelist but instead just the resolvePrivateName trap. If we stick with the whitelist, don't pass the .public property to the resolvePrivateName trap  
> >  
> > TVC: Why is it a WeakSet? Because we dont want someone to provide their own collection that can extract the private data.  
> >  
> > TVC: Why is there a resolvePrivateName trap? Say an operation is performed on a proxy involving a private name, and the proxy doesn't know this private name. Two reasonable options: 1) forward to target, i dont see results, I dont care. OR 2) throw exception. A policy decision to be made by the handler: when working on a private name that we dont know about, forward or throw?  
> >  
> > DH: Should champions take this offline?  
> >  
> > STH: It's pretty important and could mean a significant simplification.  
> >  
> > WH: Would like to get rid of the public/private property flags  
> >  
> > DH: for notational convenience, would be great if one could pass an array literal as 3rd arg  
> > TVC: could specify that if 3rd arg is an array-like, we copy its elements into a built-in WeakSet
> > WH: that would be confusing: names later added to the array-like won't get added to the internal WeakSet
> >  
> >  
> > AWB: Not clear how using a built-in WeakSet will protect, what if it's been redefined? Are WeakSet methods non-writable?  
> > TVC: we need to specify that the proxy calls the original/intrinsic WeakSet.prototype.get method.
> >  
>  
> Typof. I think you meant WeakSet.prototype.has (WeakSets have no "get").
>  
> >  
> > STH/LH/RW: Will need to spec WeakSet  
> >  
> > **Conclusion/Resolution**  
> > Yes to third arg for whitelist, pending details to be worked out by Proxy champions.
> >  
> > Expect to remove the "public" part of private names.   
> >  
> >  
> > ## WeakSet   
> >  
> > DH: Clear that we need WeakSet to match WeakMap (Set and Map)  
> >  
> > AWB: Need to assure that WeakMap and WeakSet are not redefined? Application code can enforce that if necessary:
>  
>     Object.defineProperty(this, 'WeakSet', {configurable: false, writable: false});
>  
> > RW: Use cases in node programs where I'm using WeakMap made it apparent that it _is_ possible to leak via redefinition. The first code that runs in a fresh ECMAScript environment is the one in charge of deciding what can be redefined and what cannot.
> The first code that runs decides of the security policy. If it's a defender, it can freeze built-ins. If it's an attacker, it can redefine built-ins in harmful way.
> If no choice is made by the first code, the next piece of code decides and so on.
>  
> In my opinion, the structure of any secure and reliable JavaScript (ES5) application should be like:
> 1) enhance environment (polyfills, libraries, etc.)
> 2) freeze built-ins (via initSES.js or equivalent)
> 3) application code
>  
> ES6 Modules may change this. I haven't given much thoughts of how it does.
>  
> David

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.mozilla.org/pipermail/es-discuss/attachments/20120928/7fcd999d/attachment-0001.html>


More information about the es-discuss mailing list