W3C home > Mailing lists > Public > public-script-coord@w3.org > October to December 2012

Re: WindowProxy objects violate ES5 invariants

From: David Bruant <bruant.d@gmail.com>
Date: Thu, 13 Dec 2012 18:24:51 +0100
Message-ID: <50CA0F63.8030007@gmail.com>
To: Boris Zbarsky <bzbarsky@MIT.EDU>
CC: public-script-coord@w3.org
Le 13/12/2012 17:14, Boris Zbarsky a écrit :
> On 12/13/12 6:01 AM, David Bruant wrote:
>> whenever the underlying window of a WindowProxy can change
>
> Which is always.
When a script in a page has access to its global object, this object is 
a WindowProxy. In this case, under which conditions can the underlying 
window object change? (and that change be observable by the same script, 
of course)

>> the internal operations ([[DefineOwnProperty]],
>> [[GetOwnProperty]]) must throw whenever they're about to commit to an
>> invariant.
>
> That's not ok, unfortunately, because for security reasons we must be 
> able to define things that look like non-configurable properties on a 
> window.
By "we", you mean "implementors" and that's fine. Only web authors won't 
be able to define their own non-configurable properties.

> Specifically, window.location needs to behave as if it were 
> non-configurable for all intents and purposes; see the [Unforgeable] 
> annotation in the spec there.
 From what I understand, [Unforgeable] means that 'location' is an own 
non-configurable property. I think I understand that since location is 
readonly, it only has a getter (tell me if I'm missing something). If 
'location' is indeed reflected as a getter, then, everything is fine.

 From the programmer point of view, 'location' is a non-configurable 
getter, so it's normal to be able to return different values over time.
Also, since all Window instances have the same set of [Unforgeable] 
properties, no non-configurable-related invariant is violated when a 
WindowProxy changes of underlying window instance.

For [Unforgeable] properties, it's fine to reflect them as 
non-configurable, because the invariants bound to the definition of what 
[Unforgeable] means are compatible with ES5 invariants.

>> More concretely, it means that a WindowProxy which can has its window
>> changed can't be made non-extensible
>
> This part is probably fine, though.
Ok, good to know. (I think I had tried already, so I wasn't really 
worried about this part)

>> This change is not compatible with what's currently implemented in both
>> Chrome and Firefox, but I'm confident ES5 Object methods are not used a
>> lot in content and even less likely on WindowProxy instances, so I think
>> it's worth trying.
>
> So what do you propose getOwnPropertyDescriptor return for 
> window.location?
{get: function(){}, configurable: false, enumerable: true}. No matter if 
the underlying window changes, this returned value is consistent over 
time thanks to the definition of [Unforgeable].
The problem is for user-added non-configurable properties which 
magically disappear while they shouldn't (as in my example).


>> It's been pointed that a script can add a non-configurable property to
>> its global object [5] and there is no reason to prevent that. So from
>> the spec perspective, there would bit 2 types of WindowProxy:
>> * Those which are guaranteed to never change the underlying window (and
>> can add non-configurable properties)
>> * Those which can change the underlying window (and should never do
>> anything committing to invariants)
>
> How would you decide which one to use, exactly, when you have to hand 
> out a WindowProxy?
I thought that there were some circumstances (see above) where a 
WindowProxy "can't" have its underlying window changed. If that's not 
the case, then, the first part doesn't matter.

>> What do you think of the problem?
>
> It seems like a pretty abstract problem with not much relevance to 
> actual web authors, honestly.  I can see how it's a problem for 
> internal consistency, of course...
ES5 added the invariants to make ECMAScript friendly to defensive 
programming (where you need your own code to guarantee some invariants). 
I think defensive programming is actually relevant anytime you bring a 
script from a not-fully trusted source and that script interacts with 
yours. But i agree, few people care. For those who do, it may be 
critically important

If the web browser provides objects that question the invariants, then 
security assumptions are questioned and so is the security of the 
application.

More relevant to implementors, having WindowProxy respecting ES5 
invariants enable them to be self-hosted in ES6 and be implemented with 
ES6 proxies. I think that'd be a win, no?

>> What do you think of the suggested solution?
>
> I'm still trying to understand the proposal.
The core of it is having WindowProxy instances prevented from accepting 
user-added non-configurable properties (as you made me realize, 
[Unforgeable] properties are fine)

I'm happy to answer any question.

Thanks a lot for your time and your answers,

David
Received on Thursday, 13 December 2012 17:25:28 UTC

This archive was generated by hypermail 2.3.1 : Wednesday, 8 May 2013 19:30:08 UTC