Re: WindowProxy objects violate ES5 invariants

On Thu, Dec 13, 2012 at 10:37 AM, Boris Zbarsky <bzbarsky@mit.edu> wrote:
> On 12/13/12 12:24 PM, David Bruant wrote:
>>
>> 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)
>
>
> When the window is navigated or document.open() is called.
>
> Here's a simple testcase that shows the underlying window changing:
>
> test2.html:
>   <script>
>     var self = window;
>     var foo = 1;
>     var f = function() { alert(foo); alert(self.foo); }
>   </script>
>
> test.html:
>
>   <iframe src="test2.html"></iframe>
>   <script>
>     window.onload = function() {
>       window.f = frames[0].f;
>       f();
>       var i = document.querySelector("iframe");
>       i.setAttribute("onload", "f()");
>       frames[0].location = "about:blank";
>     }
>   </script>
>
> This alerts 1, 1, 1, undefined in at least Safari, Opera, Firefox.
>
>
>>> 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.
>
>
> I don't see how that's OK.  "we" as in implementors are using the same APIs
> to define our properties...
>
> It seems like you're just taking one bit of magic and replacing it with
> another, just as bad, bit of magic.  What's the win?
>
>
>>  From what I understand, [Unforgeable] means that 'location' is an own
>> non-configurable property.
>
>
> That's correct.
>
>
>> 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.
>
>
> So the key here is that it's not just a getter but that this getter is
> always present on all Window objects, right?

Yes, it must be one stable getter property with the same getter. All
the "switching" has to be magic behavior within that getter.



>
> Note also that there may be some cases in which a WindowProxy will simply
> stop pointing to any Window completely.  I don't know whether any of these
> are (yet?) exposed to the web platform...

I'm surprised by this and it sounds important. Could you expand?


>
>
>> More relevant to implementors, having WindowProxy respecting ES5
>> invariants enable them to be self-hosted in ES6 and be implemented with
>> ES6 proxies.
>
>
> This is an argument I would have an easier time buying if we don't then turn
> around and say that there's magic implementors can do that authors can't
> like you do above....

As you correctly point out, implementors must not violate these
invariants either. If they do, the resulting system violates ES5. A
single invariant-violating object can be leveraged by direct proxies
to create any number of other objects that also violate invariants.


>
> -Boris
>



--
    Cheers,
    --MarkM

Received on Thursday, 13 December 2012 18:44:00 UTC