Skip to content

Use of source browsing context in navigation seems totally broken to me #1130

Closed

Description

@bzbarsky

The way HTML does navigation is that the input is a "source browsing context". This is then used in phrases like "the origin of the source browsing context" (not defined anywhere; browsing contexts don't have origins) and "Set request's client to the source browsing context's active document's Window object's environment settings object".

The problem is that the active document of the source browsing context may not be the document responsible for the navigation, no? Unless we're very careful to ensure that scripts in no-longer-active documents can't perform window.open (even on other windows!), can't submit forms, can't trigger targeted anchors, etc. I'm pretty darned sure nothing prevents the window.open thing, at least.

We should really be passing in the source window or source document or something here.

Activity

  1. annevk commented on Apr 26, 2016

    @annevk
    Member

    That makes sense. (FWIW, see #1117 and #1128 for some initial cleanup of the navigate algorithm. If those land, I plan on producing a lot more. Really want to get it in a much better shape.)

  2. annevk commented on Apr 28, 2016

    @annevk
    Member

    As far as I can tell this is the concept that Fetch calls "client". That would mean that the relevant settings object of the active document would be the way to go.

  3. annevk commented on Apr 28, 2016

    @annevk
    Member

    Perhaps we should also start calling it the "client" parameter to the navigate algorithm to indicate the break from the broken current pattern.

  4. self-assigned this
    on Apr 28, 2016
  5. bzbarsky commented on Apr 28, 2016

    @bzbarsky
    ContributorAuthor

    That would mean that the relevant settings object of the active document would be the way to go

    Even when the navigation was started by one of the inactive documents?

    I agree that fundamentally what we want here is the Fetch "client".

  6. annevk commented on Apr 28, 2016

    @annevk
    Member

    Even when the navigation was started by one of the inactive documents?

    Ah, window.open() and similar cases. I'm not sure what would be best. "Current settings object"?

  7. bzbarsky commented on Apr 28, 2016

    @bzbarsky
    ContributorAuthor

    We should start by checking what UAs actually do...

  8. annevk commented on May 2, 2016

    @annevk
    Member

    Here's a simple test using window.open() from an <iframe>. It seems to have no effect: http://software.hixie.ch/utilities/js/live-dom-viewer/saved/4130. @domenic thoughts? You're way better versed in this than I am.

  9. domenic commented on May 2, 2016

    @domenic
    Member

    I am? Dang now I have to try to understand this issue... Will give it a try later today or tomorrow.

  10. bzbarsky commented on May 2, 2016

    @bzbarsky
    ContributorAuthor

    It seems to have no effect:

    No effect in what sense? This open() call is being blocked by the popup blocker, right? Try http://software.hixie.ch/utilities/js/live-dom-viewer/?saved=4132 and click the button.

  11. bzbarsky commented on May 2, 2016

    @bzbarsky
    ContributorAuthor

    Oh, and what http://software.hixie.ch/utilities/js/live-dom-viewer/?saved=4132 shows is that the referrer being used for window.open is coming from either the incumbent global or the entry global, not from the current or relevant global. I think.

  12. annevk commented on May 2, 2016

    @annevk
    Member

    I meant that the referrer is not coming from the <iframe>, sorry.

  13. bzbarsky commented on May 2, 2016

    @bzbarsky
    ContributorAuthor

    OK, true, and useful data. But that's not quite exercising the case I was really worried about above.

    The case I was worried about above is what happens when a window.open call happens and the incumbent global (and/or the entry global if we can arrange that somehow) corresponds to a no-longer-active document. In other words, load some frame, grab a function f from it, where f performs a window.open() call on some window (probably not the iframe's window itself, though it's interesting to test how UAs handle that too; I know Firefox has some security checks around it). Then navigate the iframe so the global of f corresponds to a no-longer-current document. Then call f either from your own script (so you're entry but f is incumbent) or by setting f as an event listener (so f is entry).

    Then see what happens.

    In practice, based on past testing I've done, I expect that the "f as event listener" case won't call the function at all in Firefox. I think it won't in IE either. Not sure about Safari/Chrome. The "f as incumbent" case will throw an exception trying to call f in at least some IE versions, but iirc call it successfully in other browsers. And the behavior in terms of whether f is called or not is quite different, with some web compat constraints, if we remove the iframe from the DOM instead of navigating it. :( None of that says what the referrer will be, of course. Or the place that determines our secure context state, for that matter (ideally this is the same thing, but I have low confidence in this being the case in specs or impls right now, because secure context state is defined in terms of openers iirc and the opener is the relevant global, I think).

    Basically, we need to write an actual set of principled tests, using wpt or something; live dom viewer poking is going to get pretty confusing, esp. as people want to add more tests and modify existing ones to test more edge cases.

  14. domenic commented on May 2, 2016

    @domenic
    Member

    OK, trying to get my head around this.

    The difference between the OP's suggestion of "source document" and using a settings object is the cases where that relationship is not 1:1. That is: the about:blank initial navigation, where a window = settings object has two documents; and document.open(), where multiple window = settings objects end up mapping to the same document.

    It's not clear to me whether these cases matter for what we're talking about, maybe because I am having trouble piecing together a comprehensive list of the ways in which source browsing context is currently used. It sounds like we have mainly that it's used as the fetch client, which impacts referrer, and ... what else?

    I guess the discussion has probably moved on beyond that and is now assuming that it should be "source settings object". Seems fine. The question is then whether the navigation algorithm, when invoked, should be invoked with the current, entry, incumbent, or relevant settings object as the "source settings object".

    I agree that a comprehensive set of tests would be helpful. It seems like we'd need a matrix of all the places that invoke the navigate algorithm, and in each case, ways to maximally vary the incumbent/entry/current/relevant settings objects, so we can see which one ends up being used. (How do we test which one is being used? I guess by making sure each is at a different URL, and then checking the resulting referrer?)

  15. 33 remaining items

  16. added a commit that references this issue on Nov 4, 2020
  17. domenic commented on Mar 15, 2021

    @domenic
    Member

    Update on what's left:

    • Navigate
      • Initial synchronous "allowed to navigate" check in step 3
      • Initial synchronous "preexisting attempt to navigate" check in step 4
    • Process a navigate fetch
      • Determining user activation in step 3 for setting request's user-activation flag
      • Setting the request's client in step 2
      • Determing COOP enforcement result in step 6
    • Process a navigate response
      • Allowed to download check in step 7 (the Content-Disposition case)
    • Passing its URL or data to an external software package
      • Transient activation "should" check
    • execute a javascript: URL request
      • Same-origin check in step 2
  18. domenic commented on Mar 19, 2021

    @domenic
    Member

    Update on what's left after #6497, #6512, and #6801:

    • Navigate
      • Initial synchronous "allowed to navigate" check in step 3
      • Initial synchronous "preexisting attempt to navigate" check in step 4
      • Synchronously determining hasTransientActivation and allowedToDownload
    • Process a navigate fetch
      • Setting the request's client in step 2
      • Determining COOP enforcement result by checking its active document's origin in step 6
    • Passing its URL or data to an external software package
      • References source browsing context's active document's origin as something the UA should tell users about

    One thing I realized is that for the origin checks (which are the remaining major ones), I'm unsure whether the difference between incumbentNavigationOrigin and the source browsing context's active document's origin is intentional. I will try to do some digging in Chromium to see if that's the case.

  19. added a commit that references this issue on Oct 31, 2022
    0a97a81
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions