-
Notifications
You must be signed in to change notification settings - Fork 2.7k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
History traversal and the request's origin
.
#4446
Comments
Storing the source browsing context origin on the session history entry and using it in history navigations seems a bit strange to me. Consider navigation to A first, which navigates to B, which navigates to C. If we store the source browsing context origin, for the navigation to B that would be A. However, if document C does history.back(), then it is not very logical to use A as the origin of the source browsing context, since in reality it is document in C that caused the navigation to happen. P.S. The origin of the source browsing context is referred to as "initiator origin" in Chromium's vocabulary, so if I slip up and use it instead of the spec version, please excuse it. |
@naskooskov: What would you do for the "User clicked the browser's 'Back!' button" case? There, it seems like we need to move them back to what they were seeing previously, as that's what they're asking for. To do so, we need to recreate the context of the request, don't we? Also, to turn your example around: let's say that At core, history seems different to me than other forms of navigation. In either your example or mine, the fact that |
I think my mental model matches @mikewest's here: the "Back" button is more "take me back in time and show me the same pixels I saw" than "perform a navigation to the URL I was on before from the page I'm on now"; I think this also aligns with what bfcache implementations are doing. In that world, using the original origin of the source browsing context for a back navigation doesn't seem unreasonable. My guess is that this will become more important in a world where applications get more selective about navigations to their sensitive endpoints to protect against various classes of infoleaks, and will want to reject some cross-site requests without breaking legitimate functionality. |
One caveat here is that passing around a browsing context is wrong (you also cannot talk of an origin of a browsing context); see #1130. Source browsing context should probably be a document instead or more likely some kind of struct with the relevant state originally initialized from a document. |
I think I agree with the view that the "Back" button means "take me back in time and show me the same pixels I saw" (e.g. this is why browsers prompt and replay POST payload if needed). I also agree that having different results based on whether the page was in bfcache would be unfortunate. Still, to try to play devil's advocate - there is another security attack to consider:
If we replay the original |
Right now in Chromium all history navigations are browser-initiated, so the origin (for calculating |
Attacks based on sanitized HTML on the victim site (e.g. attacker-controlled links, etc.) are fairly interesting in this context and will probably require developers who implement navigation restrictions to do some work to prevent bypassing such restrictions. For example, if an attacker has the ability to post a link on the victim site, she can already navigate to arbitrary endpoints in the victim origin as I think the class of attacks you described is definitely worth considering, though I'm not entirely sure how risky it is to allow the attacker to re-navigate the user to a URL on which the user had legitimately landed before (it seems similar to the user refreshing the page). Especially in a world with COOP, if the application disables direct DOM access from cross-site windows, then the attacker seems to be fairly limited in what she can do after replaying the navigation. We should probably document all this... ;) |
You're right, I probably shouldn't call my scenario "an attack" - the "attacker" has very little control over the victim's URL that the user is taken back to (and AFAIK ability to control parts of the URL is necessary to bisect information leaked in a cross-site-search attack). |
I can see the point of view "get me back the same pixels" notion of back/forward navigations. But we can't do that reliably either when the server responds that the browser shouldn't cache the document. If caching is not prevented, I think history navigations just go to cache, so in those cases the headers discussion is somewhat moot. Overall I want to make sure we consider all the scenarios. |
I think I agree that session history navigations should preserve the original values for things like the request origin, so that it behaves the same on repeat visits. We've seen plenty of attacks where an attacker visits a victim page, leaves, and comes back to get different behavior (e.g., coordinated by another window), and that will likely get worse as we introduce controls like Sec-Fetch-Site. I'm not too concerned about the cases where an attacker might try to time a back navigation to somewhere you've already been-- they don't have much control over the URL in that case. Same for cached pages, which basically show what was there on the previous visit rather than what you'd get if you visited the same URL without the requesting origin in use. It's worth being explicit about what gets preserved, though, since it will likely need to be persisted to disk and restored into future sessions. Do we need more than the source document's origin? (I don't see how we would preserve a notion of the document.) |
I'd want to refresh the discussion about the issue. My perspective on the matter is very aligned with @anforowicz. Current implementation in Chromium and Firefox, when navigated back through I created a PoC to imitate a simple attack on the user, that will duplicate the original request in the first section. Another problems arises with location hash manipulations in the meantime. What if the attacker changes the URL fragment of the original window? In theory, exactly the same request goes to the server since the fragment will be ignored. Chrome will send I think it's important to distinguish between browser and page initiated navigations. |
@terjanq, are you concerned about specific XS-Leaks that might open a way for additional attacks? I think that Chromium's stance (/cc @mikewest, @csreis) is that it might be impossible to fix _all* XS-Leaks in the browser, and therefore we may need websites to help with protecting themselves against XS-Leaks by refusing to serve sensitive content in presence of FWIW, Chromium stores |
@anforowicz I am concerned that a cross-origin page can make a
I mentioned XS Leaks, as well as implemented one in the PoC, to prove that although an attacker holds no control over the URL of the attacked website, they still can detect to what page the victim navigated to, and with that, duplicate sensitive requests.
In provided PoC, what will be the expected |
I am sorry, but I don't understand how that would happen - how would the attacked detect what page the victim navigated to? I see that in the PoC the cross-site popup can see (via I also don't understand how the history behavior discussed here (whether to replay some http request headers during history navigations) is related to the XS-Leak from the PoC. I think the you are arguing that bad things happen when 1) a victim page is served with
I would expect |
XSLeaks is unrelated to the core issue, so I didn't want to go into details on how to actually detect what page the victim navigated to. It can be done by fingerprinting the page using iframes. It doesn't disclose the URL of the page, just type of the page (e.g. OAuth page)
I am arguing that replaying headers can bypass server measurements, not necessarily against XS-Leaks, but in general for cross-origin requests. With a single user interaction, e.g. transferring money to the attacker, the attacker can duplicate the requests infinitely, from a cross-origin page. In the PoC, only requests with |
This was fixed by #6315: the initiator origin is now stored and tracked in https://html.spec.whatwg.org/#document-state-initiator-origin. |
Step 5.10 of https://fetch.spec.whatwg.org/#http-network-or-cache-fetch serializes a
request
'sorigin
in order to generate anOrigin
header. It's not clear to me what that's going to be for a navigation generated from history traversal.Step 1.3 of traversing the history suggests that we ought to perform the navigation using the "same source browsing context as was used the first time [the] entry was created" (which then populates the request's origin by virtue of being assigned as the request's
client
in step 2 of "process a navigate fetch". I don't think that's technically possible in most cases, as the source browsing context has almost certainly been discarded, or is otherwise unavailable.Perhaps it would make sense to store some of the information about the source browsing context on the session history entry instead, so that it can be passed into the navigation algorithm in some way that supports doing the right thing for the
Origin
header (as well asSec-Fetch-Site
andSameSite
cookies, which will have similar requirements on therequest
's data)./cc @naskooskov, @anforowicz, @csreis
(I'm not exactly sure what #3625 is asking for... this bug might be a more-specific dupe?)
The text was updated successfully, but these errors were encountered: