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 26317 - Clarify action of sandboxing flags when following hyperlinks with a user indicated specific browsing context
Summary: Clarify action of sandboxing flags when following hyperlinks with a user indi...
Status: RESOLVED WORKSFORME
Alias: None
Product: WHATWG
Classification: Unclassified
Component: HTML (show other bugs)
Version: unspecified
Hardware: Other other
: P3 normal
Target Milestone: Unsorted
Assignee: Ian 'Hixie' Hickson
QA Contact: contributor
URL:
Whiteboard:
Keywords:
Depends on:
Blocks:
 
Reported: 2014-07-12 14:45 UTC by Bob Owen
Modified: 2015-01-15 23:40 UTC (History)
3 users (show)

See Also:


Attachments

Description Bob Owen 2014-07-12 14:45:33 UTC
If we have a sandboxed iframe that contains a hyperlink.

The first paragraph of [1] step 3, deals with the user indicating a specific browsing context.
Should the sandboxing flags still be applied?

In particular how should we handle the following scenarios:

* If it is a new browsing context (e.g. from Ctrl+click or context sensitive menu), should the sandboxed auxiliary navigation browsing context flag prevent the new browsing context from being created?
Currently, I think this only happens as part of [2], which doesn't happen in this case.

* If it is a new browsing context and they are applied, if allow-popups is specified should the sandboxing flags be copied to the new browsing context and the one permitted sandboxed navigator set.
Again this is only covered in [2].

* If it is an existing browsing context (e.g. by dragging the link to an existing tab), should we apply sandboxing.
In this case, because it is handled by step 2 of [3], it would seem that we should and it would only be allowed if the source were the one permitted sandboxed navigator.


At least some of these would also seem to apply to the example of control-clicking for window.open given at [4].

Thanks.


[1] http://www.whatwg.org/specs/web-apps/current-work/multipage/links.html#following-hyperlinks-2
[2] http://www.whatwg.org/specs/web-apps/current-work/multipage/browsers.html#the-rules-for-choosing-a-browsing-context-given-a-browsing-context-name
[3] http://www.whatwg.org/specs/web-apps/current-work/multipage/history.html#navigate
[4] http://www.whatwg.org/specs/web-apps/current-work/multipage/browsers.html#dom-open
Comment 1 Ian 'Hixie' Hickson 2014-07-30 22:23:14 UTC
The first paragraph of the "follows a hyperlink" text applies after the "activation behavior of a elements that create hyperlinks" have executed. Those check for sandboxing and so forth before calling "follow the hyperlink". Similarly, window.open(), after it's selected a browsing context, checks whether sandboxing is enabled before doing anything with the selected browsing context.

However, those steps have wiggle room for the browser to allow the user to override the selected browsing context in the case of sandboxing ("The user agent may offer...").

The net result of all this is that it is mostly up to the UA.

Does this answer your question? Is there a specific case you'd like more carefully examined?
Comment 2 Bob Owen 2014-08-19 12:20:14 UTC
Sorry about the delay in getting back to you on this.
(Boris - should probably have copied you in before.)

(In reply to Ian 'Hixie' Hickson from comment #1)
> The first paragraph of the "follows a hyperlink" text applies after the
> "activation behavior of a elements that create hyperlinks" have executed.
> Those check for sandboxing and so forth before calling "follow the
> hyperlink".

Ah, hadn't spotted these checks before.
Doesn't this mean that we have to run the rules at [1] twice? Once here and again in step 3 of [2].

The behaviour depends on whether the user indication of a specific browsing context is taken to have happened before activation or after.
At the moment I can only see it mentioned after in step 3 of [2], although I may have missed something again.

Looking at the first scenario in the description.
If we had an iframe that is sandboxed without any keywords, that contains an "a" element with a target of _top and the user Control-clicks it, we would:

* Run [1] as part of activation, which would return our top level browsing context and so not abort.
* Then in step 3 of [2], as the user has indicated a specific browsing context (i.e. a new one via the Control-click, which has been created outside of [1]), target gets set to that.
* The navigation would then fail, as we wouldn't be the one permitted sandboxed navigator of the new browsing context.

So, it seems that it only makes sense for any user indication of the target to treated as if it has happened before activation. Maybe this could be stated in the activation steps.

> Similarly, window.open(), after it's selected a browsing
> context, checks whether sandboxing is enabled before doing anything with the
> selected browsing context.
>
> However, those steps have wiggle room for the browser to allow the user to
> override the selected browsing context in the case of sandboxing ("The user
> agent may offer...").
> 
> The net result of all this is that it is mostly up to the UA.

Again I may be missing it, but the sandboxing checks for window.open() only seem to happen in [1] and [3].
I don't see anything in the window.open() text.
Both [1] and [3] say the user agent can allow a different (possibly new) top-level browsing context to be chosen, when blocked by sandboxing.
But that is slightly different to the case where a different browsing context is chosen in advance (by Control-click, dragging, etc.).

It seems that in these cases the running of [1] should be done with a target of _blank, if a new context is chosen (e.g. by Control-click) or should not be run at all if an existing browsing context is chosen (e.g. by dragging).
That way, when the document that contains the link is sandboxed, the new context would be blocked in [1] if allow-popups is not specified and the existing navigation would be blocked in [3], if the source is not allowed to navigate the target by sandboxing.

I seem to have rambled a bit there, but hopefully it makes sense.


[1] http://www.whatwg.org/specs/web-apps/current-work/#the-rules-for-choosing-a-browsing-context-given-a-browsing-context-name
[2] http://www.whatwg.org/specs/web-apps/current-work/#following-hyperlinks-2
[3] http://www.whatwg.org/specs/web-apps/current-work/#navigate
Comment 3 contributor 2014-09-16 20:32:59 UTC
Checked in as WHATWG revision r8776.
Check-in comment: Try to fix the logic around opening new tabs because the user said so, even in sandboxed environments
https://html5.org/tools/web-apps-tracker?from=8775&to=8776
Comment 4 Ian 'Hixie' Hickson 2014-09-16 21:19:12 UTC
(In reply to Bob Owen from comment #2)
> Doesn't this mean that we have to run the rules at [1] twice? Once here and
> again in step 3 of [2].

Well, the "rules for choosing a browsing context given a browsing context name" are only hypothetically run by the "activation behavior of a elements" (it says "if [...] applying the rules for choosing a browsing context given a browsing context name [...] *would* result"). So you only actually run them once.


> The behaviour depends on whether the user indication of a specific browsing
> context is taken to have happened before activation or after.

The user input is what triggers the activation. How can it happen after?


> At the moment I can only see it mentioned after in step 3 of [2], although I
> may have missed something again.

Hm, yeah, the activation behaviour should probably sidestep the "rules for choosing a browsing context given a browsing context name" when there's a user-specified browsing context. Fixed.


> If we had an iframe that is sandboxed without any keywords, that contains an
> "a" element with a target of _top and the user Control-clicks it, we would:

This would now work as follows:

 – The activation behaviour does nothing except "follow the hyperlink".
 – "Follow the hyperlink" uses the user-specified browsing context, and marks
   the source browsing context as the "one permitted sandboxed navigator" of
   the new one.
 – The "navigate" algorithm would then check "allowed to navigate", which would
   terminate positively.
 - New tab gets navigated.

I've also updated the window.open() text. (In a separate diff I'll turn that algorithm into clearer steps.)

Does the updated text make this clearer?
Comment 5 contributor 2014-09-16 21:23:57 UTC
Checked in as WHATWG revision r8777.
Check-in comment: Recast window.open() in terms of an algorithm.
https://html5.org/tools/web-apps-tracker?from=8776&to=8777
Comment 6 Bob Owen 2014-09-17 08:01:03 UTC
(In reply to Ian 'Hixie' Hickson from comment #4)

Just reading through the comment looks promising, thanks.
However, I'm just about to leave for the airport and I'm not sure what sort of internet access I'll have for the next week, so I'll have a look in more detail when I get back.
Comment 7 Ian 'Hixie' Hickson 2014-09-24 19:05:57 UTC
Bob, is there anything else you think should be updated?
Comment 8 Bob Owen 2014-09-26 11:30:18 UTC
Sorry about the delay in getting back to you.
I only arrived back in the early hours yesterday and I knew that this would take a bit of time to read and think through.

(In reply to Ian 'Hixie' Hickson from comment #4)
> (In reply to Bob Owen from comment #2)
> > Doesn't this mean that we have to run the rules at [1] twice? Once here and
> > again in step 3 of [2].
> 
> Well, the "rules for choosing a browsing context given a browsing context
> name" are only hypothetically run by the "activation behavior of a elements"
> (it says "if [...] applying the rules for choosing a browsing context given
> a browsing context name [...] *would* result"). So you only actually run
> them once.

Surely the only way that you can determine what the result of an algorithm will be, is by actually running that algorithm (or an equivalent one).

> > At the moment I can only see it mentioned after in step 3 of [2], although I
> > may have missed something again.
> 
> Hm, yeah, the activation behaviour should probably sidestep the "rules for
> choosing a browsing context given a browsing context name" when there's a
> user-specified browsing context. Fixed.

I think these changes hang together, but I'm a bit concerned about one of the implications.
As the "allow-popups" check and the sandbox flag copying is only done in the "rules for choosing...", if a new top-level browsing context is chosen we don't make this check at all.
We end up with a new un-sandboxed top-level browsing context with our sandboxed source browsing context set as the one permitted sandboxed navigator.
So, if the user can be persuaded to Ctrl-click or middle-click on a link you can effectively escape the sandbox.

When the user indicated browsing context is an existing one the sandbox will take effect, because it is enforced as part of the navigation.
This makes things a bit inconsistent.

If we want to change this we could pass a target of _blank to the "rules for choosing...", which would then do the security check and any flag copying.
However, this seems like a bit of a hack and I have never quite liked the fact that the "rules for choosing..." do the actual creating of the new top-level browsing context.

It seems to me that Step 5 to the end along with the "allowed to show a popup" section could be moved into a new "Create a top-level browsing context" algorithm, which would do all the security checks as well as the flag copying.

Then any user indicated new browsing context sections could call this.
To save on too many changes at once the "rules for choosing..." could also call this.
I personally think it would be better if they eventually just did the search part of the algorithm and left it up to the caller as to whether the "Create a top-level browsing context" algorithm should be called when no existing one can be found.
 
> I've also updated the window.open() text. (In a separate diff I'll turn that
> algorithm into clearer steps.)
> 
> Does the updated text make this clearer?

I certainly prefer the algorithmic style, but I dare say others would disagree.
I notice that we have a change in behaviour for when the URL is empty, as in the non-new case it no longer gets defaulted to about:blank and the navigation is skipped.
This also means that the WindowProxy of the target browsing context is always returned even if no navigation takes place.
This might allow a sandboxed browsing context to get hold of a WindowProxy by name that it might not have been able to in the past. Although other security restrictions should limit what it could do with it.

The behaviour for when the URL resolution fails also seems to have changed slightly, but this appears to be optional.
Comment 9 Ian 'Hixie' Hickson 2014-10-10 18:20:02 UTC
(In reply to Bob Owen from comment #8)
> 
> Surely the only way that you can determine what the result of an algorithm
> will be, is by actually running that algorithm (or an equivalent one).

Nah. We can reason about what would happen by looking at the spec without actually doing what the algorithm says. Equivalently, a browser could have a similar algorithm that does the same checks but without the side-effects.


> As the "allow-popups" check and the sandbox flag copying is only done in the
> "rules for choosing...", if a new top-level browsing context is chosen we
> don't make this check at all.
> We end up with a new un-sandboxed top-level browsing context with our
> sandboxed source browsing context set as the one permitted sandboxed
> navigator.
> So, if the user can be persuaded to Ctrl-click or middle-click on a link you
> can effectively escape the sandbox.

Right. That's intentional. There has to be _some_ way for the user to unsandbox content.


> When the user indicated browsing context is an existing one the sandbox will
> take effect, because it is enforced as part of the navigation.
> This makes things a bit inconsistent.

I agree it's a bit inconsistent. Not sure how important this is in practice. There's not really a way for a user to specify an existing browsing context...


> It seems to me that Step 5 to the end along with the "allowed to show a
> popup" section could be moved into a new "Create a top-level browsing
> context" algorithm, which would do all the security checks as well as the
> flag copying.
> 
> Then any user indicated new browsing context sections could call this.
> To save on too many changes at once the "rules for choosing..." could also
> call this.
>
> I personally think it would be better if they eventually just did the search
> part of the algorithm and left it up to the caller as to whether the "Create
> a top-level browsing context" algorithm should be called when no existing
> one can be found.

Yeah, maybe. I'm very reluctant to make any substantial change to this part of the spec given how much depends on it and how fragile it is, though...


> I notice that we have a change in behaviour for when the URL is empty, as in
> the non-new case it no longer gets defaulted to about:blank and the
> navigation is skipped.

Yeah, this was an unrelated fix to match browsers better.


> This also means that the WindowProxy of the target browsing context is
> always returned even if no navigation takes place.

I believe this matches implementations.
Comment 10 Bob Owen 2014-10-13 13:09:58 UTC
(In reply to Ian 'Hixie' Hickson from comment #9)

Just a few more thoughts.
I don't want to waste your time, so feel free to set to resolved, if you don't think they warrant further discussion.

> > So, if the user can be persuaded to Ctrl-click or middle-click on a link you
> > can effectively escape the sandbox.
> 
> Right. That's intentional. There has to be _some_ way for the user to
> unsandbox content.

To be honest, I'm not an expert on the security implications of such things, but wouldn't we want something a little less straight forward.
Ctrl or middle click seem like things you might easily persuade someone to do.
They can always copy and paste the link into a new tab.

> > When the user indicated browsing context is an existing one the sandbox will
> > take effect, because it is enforced as part of the navigation.
> > This makes things a bit inconsistent.
> 
> I agree it's a bit inconsistent. Not sure how important this is in practice.
> There's not really a way for a user to specify an existing browsing
> context...

What about dragging a link to a tab?
Firefox, Chrome and Opera (and probably others) allow this.
Although, this does currently appear to be treated as if it were just a copy and paste of the link target.

Out of interest I did some testing with this URL:
data:text/html,<iframe sandbox src="data:text/html,<a target='_top' href='http://example.com'>example</a>"></iframe>

Chrome and Opera:
Ctrl/middle-click: blocked with sandboxing error message about allow-top-navigation not being set in console
Right click, open in New Tab: allowed
Drag to tab: allowed

Firefox:
Ctrl/middle-click: allowed
Right click, open in New Tab: allowed
Drag to tab: allowed

> > It seems to me that Step 5 to the end along with the "allowed to show a
> > popup" section could be moved into a new "Create a top-level browsing
> > context" algorithm, which would do all the security checks as well as the
> > flag copying.
> > 
> > Then any user indicated new browsing context sections could call this.
> > To save on too many changes at once the "rules for choosing..." could also
> > call this.
> >
> > I personally think it would be better if they eventually just did the search
> > part of the algorithm and left it up to the caller as to whether the "Create
> > a top-level browsing context" algorithm should be called when no existing
> > one can be found.
> 
> Yeah, maybe. I'm very reluctant to make any substantial change to this part
> of the spec given how much depends on it and how fragile it is, though...

I've got a lot less (read no :-) ) experience of spec editing, but I wonder if the fragility might stem from the fact that it is responsible for both the search and opening a new context when one isn't found.
Comment 11 Ian 'Hixie' Hickson 2014-11-07 22:18:35 UTC
(In reply to Bob Owen from comment #8)
> 
> Surely the only way that you can determine what the result of an algorithm
> will be, is by actually running that algorithm (or an equivalent one).

No, not at all. For example, suppose one has a glass jug on a table, full of water, and one has an algorithm that consists of pouring the water out of the jug. One could say "what would the air volume of the jug be if the algorithm was run", and one could calculate that without pouring the water out.

Similarly here, you can make many determinations about the results that running the algorithm would have without running the algorithm (or at least, without running it so much that you get the actual side-effects).


> As the "allow-popups" check and the sandbox flag copying is only done in the
> "rules for choosing...", if a new top-level browsing context is chosen we
> don't make this check at all.

This is intentional.


> So, if the user can be persuaded to Ctrl-click or middle-click on a link you
> can effectively escape the sandbox.

Yes. But at that point you're a top-level browsing context anyway. This is no different than convincing someone to follow a link in an e-mail. The threat model of the Web assumes that you can convince people to do this trivially.


> When the user-indicated browsing context is an existing one the sandbox will
> take effect, because it is enforced as part of the navigation.
> This makes things a bit inconsistent.

A little, yes. But I think it's good enough.


I agree that the algorithms could be reworked. The cost of doing that is relatively high, and the gain relatively low, so I'm punting on doing this. If anyone feels like taking over this part of the spec...


> I notice that we have a change in behaviour for when the URL is empty, as in
> the non-new case it no longer gets defaulted to about:blank and the
> navigation is skipped.

Yes, turns out this is needed for compatibility.


> This also means that the WindowProxy of the target browsing context is
> always returned even if no navigation takes place.

Right.


> This might allow a sandboxed browsing context to get hold of a WindowProxy
> by name that it might not have been able to in the past. Although other
> security restrictions should limit what it could do with it.

I think we assume that it could have gotten hold of it before anyway (e.g. open a page into it, then have the page navigate back).
Comment 12 Bob Owen 2014-11-08 20:21:37 UTC
(In reply to Ian 'Hixie' Hickson from comment #11)
> (In reply to Bob Owen from comment #8)

Er, I think you've replied again to my previous comment (#8) instead of comment 10.
Comment 13 Ian 'Hixie' Hickson 2014-11-12 19:05:38 UTC
Um, oops. Sorry about that.

(In reply to Bob Owen from comment #10)
> > 
> > Right. That's intentional. There has to be _some_ way for the user to
> > unsandbox content.
> 
> To be honest, I'm not an expert on the security implications of such things,
> but wouldn't we want something a little less straight forward.
> Ctrl or middle click seem like things you might easily persuade someone to
> do.
> They can always copy and paste the link into a new tab.

This is no different than convincing someone to follow a link in an e-mail. The threat model of the Web assumes that you can convince people to do this trivially.



> > I agree it's a bit inconsistent. Not sure how important this is in practice.
> > There's not really a way for a user to specify an existing browsing
> > context...
> 
> What about dragging a link to a tab?
> Firefox, Chrome and Opera (and probably others) allow this.
> Although, this does currently appear to be treated as if it were just a copy
> and paste of the link target.

Yeah, that's just taking the URL and saying "go there", it's not running these algorithms at all.


> > Yeah, maybe. I'm very reluctant to make any substantial change to this part
> > of the spec given how much depends on it and how fragile it is, though...
> 
> I've got a lot less (read no :-) ) experience of spec editing, but I wonder
> if the fragility might stem from the fact that it is responsible for both
> the search and opening a new context when one isn't found.

The fragility comes from how crazy the underlying requirements are, mostly. But yes, the spec being written as-is doesn't help. However, changing how the spec is written is a lot of work that IMHO is hard to justify given the minimal benefits and the corresponding opportunity cost and danger of accidentally breaking behaviour.
Comment 14 Bob Owen 2014-11-17 10:22:08 UTC
(In reply to Ian 'Hixie' Hickson from comment #13)

OK, thanks Ian.
Looks like Gecko is generally compliant then, aside from a one minor thing.
Comment 15 Ian 'Hixie' Hickson 2015-01-15 23:40:57 UTC
I'm closing this bug WORKSFORME since it seems that, aside from a rather significant editorial change that would improve the spec's readability that I don't want to do, there are no pending requests for changes here. Please do repopen if I missed something.