Function identity of non-configurable accessors

David Bruant bruant.d at gmail.com
Wed Dec 19 06:18:45 PST 2012


Le 19/12/2012 14:38, Tom Van Cutsem a écrit :
> I too find the solution of non-configurable data properties 
> masquerading as configurable data properties bothersome. We have a 
> mechanism in place for describing the behavior of ES5 properties, yet 
> here is a case where we can't be honest about a property's real 
> behavior. That smells.
That smell is partially a consequence of configurable being overloaded. 
At the same times, configurable:false means "the property can't 
disappear" and "applying the 'delete' operator fails" as a corrolary.
We're in a case (WindowProxy) where we want the property to disappear, 
but 'delete' to fail.

> The issue seems to be that there are two "access rights" to this data 
> property: external clients are only allowed to read, but not write to 
> the property (that is why it should really be reflected to clients as 
> non-configurable). Some privileged code, however, is allowed to write 
> to the property (that is why we cannot really make it non-configurable).
>
> Implementing these access rights is easy to achieve using an accessor 
> property, so it seems logical to turn this property into an accessor.
>
> Why can't we make it a non-configurable accessor property? I don't 
> understand the leak described by David in the OP.
The leak is very specific to the WindowProxy case

     // # Inside an iframe
     var locationPropDesc = Object.getOwnPropertyDescriptor(window, 
'location');
     assert(locationPropDesc.configurable ===  false);
     // 'false' is the current WebIDL definition of [Unforgeable] properties
     // but consensus seems to be that WindowProxy [Unforgeables] would 
be 'true'

     var locationGetter = locationPropDesc.get;
     locationGetter.cap = whatever;


     // # Outside the iframe
     var win = iframe.contentWindow;
     var cap = Object.getOwnPropertyDescriptor(win, 'location').get.cap;

     iframe.src = "somewhere else";



     // # inside the iframe *after* the navigation
     var locationPropDesc = Object.getOwnPropertyDescriptor(window, 
'location');
     assert(locationPropDesc.configurable ===  false);

     var locationGetterInsideIframe = locationPropDesc.get;

The part where it gets tricky is here. If window.location is indeed 
non-configurable and getter identity is preserved (observable from 
outside the iframe), then locationGetterInsideIframe has a property 
"cap" which value comes from the previous browsing context in the 
iframe. That's the leak. We have 2 browsing contexts able to exchange 
capabilities why they probably shouldn't. I don't know if it's a bad or 
dangerous leak, but it looks very fishy.

David


More information about the es-discuss mailing list