This is an archived snapshot of W3C's public bugzilla bug tracker, decommissioned in April 2019. Please see the home page for more details.

Bug 19662 - Consider whether the source browsing context should ever be the incumbent script rather than the entry script
Summary: Consider whether the source browsing context should ever be the incumbent scr...
Status: RESOLVED FIXED
Alias: None
Product: WHATWG
Classification: Unclassified
Component: HTML (show other bugs)
Version: unspecified
Hardware: Other other
: P1 blocker
Target Milestone: Unsorted
Assignee: Ian 'Hixie' Hickson
QA Contact: contributor
URL: http://www.whatwg.org/specs/web-apps/...
Whiteboard:
Keywords:
: 19893 (view as bug list)
Depends on: 18242
Blocks:
  Show dependency treegraph
 
Reported: 2012-10-23 06:30 UTC by contributor
Modified: 2013-06-18 19:46 UTC (History)
9 users (show)

See Also:


Attachments

Description contributor 2012-10-23 06:30:07 UTC
Specification: http://www.whatwg.org/specs/web-apps/current-work/
Multipage: http://www.whatwg.org/C#the-location-interface
Complete: http://www.whatwg.org/c#the-location-interface

Comment:
Consider whether the source browsing context should ever be "the script that
invoked the method" rather than the entry script. Affects various places in
the spec. Maybe it should just be an override referrer, though.

Posted from: 76.102.14.57
User agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_8_2) AppleWebKit/537.4 (KHTML, like Gecko) Chrome/22.0.1229.94 Safari/537.4
Comment 3 Ian 'Hixie' Hickson 2013-03-05 23:47:34 UTC
Referer: http://www.hixie.ch/tests/adhoc/http/referer/001.html
Comment 4 Ian 'Hixie' Hickson 2013-03-05 23:52:36 UTC
If we're changing the source browsing context entirely, it would be this requirement that changes:

# Navigation for the assign() and replace() methods must be done with the browsing
# context of the script that invoked the method as the source browsing context.
Comment 5 Ian 'Hixie' Hickson 2013-03-05 23:59:22 UTC
Also this bit for showModalDialog():
# with the browsing context of the script that invoked the method as the source 
# browsing context.
Comment 6 Ian 'Hixie' Hickson 2013-03-06 00:53:02 UTC
Sandboxing: http://www.hixie.ch/tests/adhoc/html/frames/iframes/sandbox/001.html
Comment 7 Ian 'Hixie' Hickson 2013-03-06 00:56:34 UTC
abarth: Can you confirm that you're still ok with changing the behaviour of WebKit on the tests in comment 3 and comment 6 to match recent Gecko? Note that the test in comment 6 involves changes to sandboxing behaviour that are technically less strict than before (though in practice only in cases where the barn door is already wiiiiide open, I think).

bz: you may be interested in the test case in comment 6; it demonstrates the case that we had talked about on the threads cited above where the requested change affects sandboxing, not just referer headers.

Unless I hear otherwise, I plan to change the spec to match Gecko (using the entry script rather than the script that most immediately triggered the navigation, for showModalDialog() and for Location objects, in selecting the source browsing context for navigation.)
Comment 8 Boris Zbarsky 2013-03-06 01:04:05 UTC
I haven't been tracking this stuff.  ccing Bobby, who probably has.
Comment 9 Bobby Holley (:bholley) 2013-03-06 17:22:25 UTC
(In reply to comment #8)
> I haven't been tracking this stuff.  ccing Bobby, who probably has.

So, my feedback in bug 19893 comment 2 still applies. I don't want the spec to bend over backward to support the easiest thing for Gecko, but making sandboxing using the script entry point might involve throwing a way a lot of efficient code that imelven is about to land in [1]. Though I'm still not totally sure that the resulting behavior ends up looking that much different.

As noted, we're implementing navigation sandboxing at property-access time using our security wrappers. So if a given scope is sandboxed, we enforce a more-restrictive set of cross-origin-accessible properties that deny write access to Window.location, Location.href, and read-access to Location.replace. This is very efficient for us given how our security wrappers work, because we only need to compute the relation between the two browsing contexts (navigator and navigatee) once, at wrap time.

Right now, sandboxing is specced in as operating during document loading. Is there a significant script-visibile difference to defining it this way as opposed to the kind of property-filtering that Gecko does? Is is script-visible at all? It seems like one could construct a counterexample with document.domain, but I haven't worked out the details.

Happy to talk about this on IRC too if you want.

[1] https://bugzilla.mozilla.org/show_bug.cgi?id=785310
Comment 10 Ian 'Hixie' Hickson 2013-03-06 22:29:10 UTC
I don't understand how comment 9 applies here. As far as I can tell, the change suggested in comment 7 is more or less trivial to make to the spec, and changes the spec to match what Gecko does today.
Comment 11 Bobby Holley (:bholley) 2013-03-06 22:55:16 UTC
(In reply to comment #10)
> and changes the spec to match what Gecko does today.

Yes, because Gecko currently doesn't implement sandbox navigation stuff correctly at all. That's what [1] is all about, where we're implementing the navigation restrictions as restrictions at property-access time. For the testcase in comment 6, our new behavior would leave us with 001a, because we'll prevent the iframe from writing to |parent.location.href|.

[1] https://bugzilla.mozilla.org/show_bug.cgi?id=785310
Comment 12 Bobby Holley (:bholley) 2013-03-06 23:31:00 UTC
Ian pointed out on IRC that there are ways for navigation to happen that don't involve script, like href target="foo". In this case, the implementation in [1] doesn't work, and we'll have to redo it.

Given that, I confirm that we're in favor of using the script entry point here.
Comment 13 Ian 'Hixie' Hickson 2013-03-25 23:22:11 UTC
*** Bug 19893 has been marked as a duplicate of this bug. ***
Comment 14 Adam Barth 2013-05-18 17:37:23 UTC
I would prefer that the spec not change in this regard.  The script that invoked the method is the one performing the action and is the one we should use for the security check.  The entry script is some distant, largely unrelated script.  We us the entry script in a few situations due to compatibility constraints, but we should be using the script that invoked the method everywhere we can, especially in new platform features.
Comment 15 Bobby Holley (:bholley) 2013-05-18 22:10:22 UTC
(In reply to comment #14)
> I would prefer that the spec not change in this regard.  The script that
> invoked the method is the one performing the action and is the one we should
> use for the security check.  The entry script is some distant, largely
> unrelated script.

Theoretically and aesthetically, I agree. But in practice, determining "the script that invoked the method" is very tricky, and not at all well-defined at this point (see bug 18242).

Suppose a and b are same origin windows. Who is the referrer in each case?

in scope a: b.location.replace(uri);
in scope a: location.replace.call(b.location, uri);
in scope a: b.location.replace.bind(b.location, uri)();
in scope a: Function.bind.call(b.location.replace, b.location, uri)();
in scope b: a.location.replace.call(location, uri); 

On the other hand, we already have the script entry point sitting around, which is very easily computable and straightforward to get right in all implementations. Since most people who care about things like document.referrer generally just want the domain, it seems like we should just use that IMO.
Comment 16 Ian 'Hixie' Hickson 2013-06-18 19:46:20 UTC
For me, the concern over the referrer really is secondary to the concern over which browsing context is used to determine whether sandboxing applies.

Up til today, the spec had:
   window.open uses the entry script's browsing context
   showModalDialog() uses the incumbent script browsing context
   location.href uses the incumbent script's browsing context
   location.reload() uses the target browsing context
   iframe.src uses the iframe's browsing context
   <meta refresh> uses the <meta>'s document's browsing context
   <a>.click() uses the <a> element's browsing context

I think we should make the first three of these consistent.

Testing window.open (using srcdoc for WebKit/Blink, and src for Firefox):
 Firefox test: http://software.hixie.ch/utilities/js/live-dom-viewer/saved/2346
 WebKit test: http://software.hixie.ch/utilities/js/live-dom-viewer/saved/2345

For both Firefox, Safari, and Chrome, the presence of the sandbox="" attribute is what affects whether window.open() can be called, consistent with the incumbent script being what matters, not the entry script. (I've now fixed the spec to use the incumbent script.)

Testing showModalDialog():
 Firefox test: http://software.hixie.ch/utilities/js/live-dom-viewer/saved/2347
 WebKit test: http://software.hixie.ch/utilities/js/live-dom-viewer/saved/2348

Same as above. This time, consistent with the spec.

Testing location.href:
 Firefox: http://software.hixie.ch/utilities/js/live-dom-viewer/saved/2349
 WebKit: http://software.hixie.ch/utilities/js/live-dom-viewer/saved/2350

Chrome and Safari use the incumbent script here, consistent with the spec.
Firefox doesn't prevent sandboxed scripts from navigating their ancestor browsing contexts at all, so it fails the control here:
   http://software.hixie.ch/utilities/js/live-dom-viewer/saved/2353


In conclusion, I've changed one occurence of "entry script" to "incumbent script" to match current browsers.


(In reply to comment #15)
> 
> Theoretically and aesthetically, I agree. But in practice, determining "the
> script that invoked the method" is very tricky, and not at all well-defined
> at this point (see bug 18242).

Right, but we'll have to define it anyway, it's used all over the place.


> Suppose a and b are same origin windows. Who is the referrer in each case?
> 
> in scope a: b.location.replace(uri);
> in scope a: location.replace.call(b.location, uri);
> in scope a: b.location.replace.bind(b.location, uri)();
> in scope a: Function.bind.call(b.location.replace, b.location, uri)();

a.


> in scope b: a.location.replace.call(location, uri); 

b.


> Since most people who care about things like document.referrer generally
> just want the domain, it seems like we should just use that IMO.

My concern isn't really over the Referer header, or even over the Origin header, but more over what happens with the security aspects, e.g. of sandboxing.