-
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
Add an API to opt-out of back-forward cache? #5744
Comments
How well is BFCache term known? I think it has had at least two meanings so far, back-forward-cache and blazingly-fast-cache. (It is still rather surprising that one can enable bfcache for pages with *unloadevent listeners.) |
Given that you're trying to cache pages aggressively, does this mean that the If we decide to add an API for disabling the BFCache and ignore WRT interoperability, I would be interested in a write-up of the behaviour and edge-cases in Chrome's new BFCache design from a spec & web-compat pov, which we could use as a springboard along with the existing Firefox & Safari BFCache designs to potentially find a more-compatible system. |
Oh, I didn't know about other uses of the name before, thanks! I think having a more descriptive name makes sense then, maybe something like Also, we might want to think on what "disable back-forward cache" means:
There are some conditions for pages to be eligible to bfcache, but yes, a lot of unload handlers won't get fired. We are providing mitigations to hopefully help with this (including the opt-out), and will reconsider if this proves to be a big problem. This is an interesting problem indeed. I've made another thread to discuss bfcache's interaction with unload & others.
Yes, this will be a great start! @altimin is actually currently working on a document that lays out these behavior differences between Chrome, Firefox, and Safari's bfcache. I think it should be ready sometime this week. We'll update this thread/the other thread with that then. |
Maybe the API name should be |
I like the
This was my intuition, and lines up Firefox's behaviour with the
I don't immediately see how that would be useful, so I'm inclined to say no. Do you have a motivating use-case for that feature?
This does seem like a potentially useful API to have. Perhaps we could have an options argument like |
If we add an API such as Safari / WebKit shipped with all pages going into the bfcache no matter what (including To address the use-case we know about, which is the log-out case, I would prefer something that would clear bfcache entries for the origin. I think I should be able to have a fast back/forward experience on my banking site so disabling the bfcache entirely on such sites would be suboptimal. However, I don't think I should be able to go back (using bfcache) after I log out of my banking site. Sadly, while something like Thoughts? |
+1 to Chris's concerns about a potential overuse of any opt-out API that we'll add. There are some tensions here between developer ergonomics and user experience and my main concern here is that by introducing this explicit API we open a way to long-term user experience losses which will increase with time as the adoption of this API increases and will be rather hard to undo. I really like the history.clear() API proposal — it's very elegant and it seems to solve a few additional problems along the way, like leaking potentially sensitive full URLs from session history in the logout case. |
Yes, that's exactly our thinking: URL, website title, website snapshot, and any other state that a browser may keep in its presentation of back / forward now or in the future -- those are all things a sensitive logout operation will want to clear, and they aren't obviously just about page persistence and caching per se. |
Would To some extent those considerations are outside of the spec, as is all browser UI, but I think it'd be worth making sure people are envisioning the same thing. |
Yes, the idea was that the user would not be about to go back after history.clear() has been called. Therefore, it would make sense to remove the corresponding same-origin (or same site?) entries in the browser UI. |
Interesting. In that case, I was initially worried about this being used for abuse to trap people on a spam site or similar, but I guess that would not be possible since it is origin-restricted. Cool 👍 |
I was a little confused about the details of the proposal reading it piecemeal in an email thread. New API - history.clear()
That additional restriction further prevents abuse with regards to a malicious site trying to cover its own tracks from browser activity unrelated to the current interaction with the page. Have I gotten this right? |
Note: Dominec had explicitly asked "(And I assume it wouldn't affect things like the dedicated history UI or location bar autocomplete...)" and then Chris agreed, but also disagreed. So this is still clearly still a point of contention. I'm 100% on the side of "This should not affect global history" |
Sorry if I wasn't clear in my reply to Domenic: I think it should impact the back button in the UI (simple press or long press to see previous history entries). However, the entries should likely stay in the "History" menu of the browser (i.e. Previously visited sites). Additionally, I think the contiguous restriction that Brady mentioned is good. That is what I had in mind although I had not written it down. |
If history.clear() would affect to session history in other tabs too, then it is worrisome. Some unrelated pages from the same origin could end up accidentally break each others. And if it doesn't affect to other tabs, then how would the log-out case work if some other tab has bfcached pages from the site? |
It would not. The history object is already well defined to be the session history for the current browsing context. E.g. the current tab. This operation would and should only clear the contiguous entries from the current browsing context's session history
The same way they are affected in logout today - not at all! If I'm logged in to a bank in multiple tabs today... and I log out in one tab, while other tabs are still ACTIVELY VIEWING MY ACCOUNT INFORMATION... I'm not protected, and it has nothing to do with the back.forward cache Of course, if a site was security conscious and concerned with this (e.g. a bank) they can coordinatedwith the other tabs through a few different mechanisms to instruct them to logout and history.clear() themselves. Or even a server side push to the other tabs, telling them to do the same thing. |
Ok, is we don't care about other tabs, but only current one, it is still very easy to break user experience if clearing all the session history entries for one site. One site may have totally unrelated pages. Silly case, but applies to me - I have various tests on my own site. They have basically nothing to do with each others. But some set of pages might be related. So I'd prefer rather some kind of history scope on a site, and then history.clear({scope: "my scope ID"}); or some such. |
That sounds like a nice idea. How to define it is an interesting problem. Wondering if we can leverage the already existing state object to fit in well. |
I think we should treat specifying a scope in this api as a “nice to have” and not a requirement. Our motivating examples — sensitive websites that need a secure log out feature — do not care to specify a scope. Requiring that a site communicate a scope across all navigations would also increase the cost of adoption and testing considerably. And there again, our motivating examples need technologies that are easy to adopt and test. That said, I don’t object to specifying a limiting scope, if we can make it optional and easy. |
Can you elaborate on why? Some reasons that a user agent may want to remove an entry from global history if the entry originated exclusively from the current back forward list and is now gone from the current back forward list:
|
The motivation for us relaxing our nearly 100% bfcache was "banks don't like that information leaks to a live page after logout"
We've never had a bank say "Don't leak our URLs or titles to global history"
We've never had a bank say "don't do all your nice UA features like snapshots and text", probably because the browsers have already been considerate in what they do or do not do here.
This is a problem much larger than the one we are trying to solve here, and making the global history change will not come remotely close to fixing it. Back to 3...
I see it as very inconsistent to give a web page control over something that is objectively a web technology - their session history entries that are already mutable in JavaScript via the history object - and also have it control something that is 100% a browser UA feature. Whereas bfcache is something all the engines have converged on and are working to make more and more effective - and therefore this conversation has come up... ...each UA having their own global history implementation and behavior is a place where they can experiment and differentiate from other UAs, all without the risk of causing web compatibility issues. Global history already has differences in behavior from session history here that makes implementing what you describe harder than you might imagine. e.g. Because the webkit.org/1.html entry got promoted in recency, not an additional one added. I would argue that the answer is both "not obvious" and "implementing it might require a non-trivial rethink of how global history works" Now repeat the above experiment intermixing with different browser tabs. Does one session in Tab A get to clear the history entries of another session in Tab B, even if Tab B doesn't want to clear global history? I would say no. What about "Top sites" type features? If I frequently visit "awesomegame.com/startpage.html" and then "awesomegame.com/endgame.html" clears all previous history... As a user I really want awesomegame.com/startpage.html in my top sites. Should the web site be allowed to prevent that? These are just a couple scenarios I conjured without much deep thought. TLDR; Session history is a web technology feature. Global history is a UA feature. |
A few questions on
On |
Actually, we have: rdar://problem/64891907.
How would clearing global history entries in response to logout cause web compatibility issues? (Seems like the change wouldn't be visible to the website at all.)
My proposal was to remove webkit.org/1.html.
I tend to agree that history-related user-facing features may differ across browsers and OS's in non-trivial ways that are hard to specify or predict. (Another example of both the need to act on other forms of history and the difficulty of specifying it is macOS's behavior of taking periodic snapshots of whole app windows.) But difficulty notwithstanding, the fact of the matter is that a UA that keeps a non-trivial record of a sensitive page after logout has created a privacy and security issue for the logged out website, and there will always be some need to resolve that issue. Perhaps the best compromise here is to specify a "must" behavior for the back-forward list, and a "should" or "should consider" behavior for other kinds of navigation history, to highlight the intention of the spec without getting too into the weeds on specific browser UIs.
Not sure I agree with the distinction being made here. What matters most is whether a website can implement a secure logout feature -- not how the technology looks from the inside. |
Perhaps I got things sidetracked with the discussion of browser UI. To be clear, browser UI is out of scope for the spec, and we won't write normative text (even of a "should" variety) for features like the back button or global history UI. I thought it would be an interesting discussion to help clarify the intention of the API, but in the end browser UI features that are not observable through JavaScript are not in scope for what we specify. |
I agree with Domenic that we can shelve the discussion about global history and related features and take it internal, as the spec has nothing to say about them. |
Session history is a sensitive thing, with the potential for pretty powerful abuse. Any modification allowed to it today (e.g. push and replaceState) is only allowed for same origin. On the shopping cart note: I've never met a site that wanted to clear a shopping cart... ;)
Personal take: I believe it solves the use case for logging out fully. |
Right, definitely not suggesting cross-origin session history modification - maybe more of a way for a page to say before leaving that it does not want to be cached (or maybe even say "you can't go back to me at all"). But thinking about this again, maybe there are really no big use cases for this, hmm... |
To provide some counterpoint to the earlier discussion: The discussion before focuses on (edit: or maybe Clear-Site-Data: "cache" already wipes the bfcache?) Yes, |
Clear-site-data could work here. One detail: this proposal is about clearing the back forward cache and the back-forward list (which might hold data like a title or a snapshot). So, you’d want a value like ‘bflist’ or ‘history’. The cache comes along for the ride with the list. |
Modifying One thing to keep in mind is making this be a header instead of a JS API is that it's harder to use (per this poll at least), which might be a good thing to discourage using this unless necessary? Also it's only possible to do it by the page itself (instead of imported script, etc). The use case we're interested in (clearing on logouts) should be fine with this though. |
I have one concern with both of these though - they all require action, so if you somehow don't call the API or supply the header, your page stays in BFCache. E.g. if
then nothing is cleared from BFCache. Is that OK? |
What does "site crashes" mean? What would be stored in the bfcache? Typing new url in to address bar should by default put the current page to bfcache - that is what I'd expect. |
In Chrome at least we can have a session history that looks like If process 2 crashes, it has no impact on process 1. It often happens that they will be in the same process but there's no guarantee.
"bank" here was just shorthand for "a site that would use the API we are discussing. The point is that we are supposing some site that is OK with having pages in BFCache as long as it has a way to kick them out. The 3 scenarios I described lead to a situation where the site still has pages in BFCache but no longer has any active page that can kick them out. Bank example - "what is wrong with keeping the previous page in bfcache?" Do we actually have any feedback from or contact with a site that is currently disabling BFCache and would use an API like the ones that have been proposed? |
This comment has been minimized.
This comment has been minimized.
See w3c/webappsec-clear-site-data#68 though. |
This comment has been minimized.
This comment has been minimized.
Places logged-in data could exist after log-out:
|
I had been thinking about pagehow as the last-resort for those who do not want to be bfcached, just delete everything from the doc and reload or show an error. In Chromium, the pageshow handlers runs synchronously as part of restore and I think 4.6.4 of the spec implies that it should. Does safari cache the pixels of the bfcached page? That would mean that pages that update on pageshow would get a flash of old content first. |
Please take a look at #5879 which wants to clarify what the overall behaviour with respect to At this point, I think we've established that we don't want an opt out but there is a legitimate case to allow sites to remove pages from BFCache. The only legit case for that seems to be dropping them after a logout. Is there any other? Is everything else "fix it in pageload"? |
Currently, we only have "implicit" ways to opt-out of bfcache that might have other side effects. A few examples from Firefox's bfcache page and problems associated with them:
I think having an explicit API to specifically opt-out of bfcache (and does nothing more than that) might be good, since there might be legitimate cases of not wanting to be bfcached (stale data/state of the previous page, logging in/out, etc.) specifically. On top of the above points, web developers have been having a hard time finding a reliable way to do just that. See [1] [2] [3] [4]. Also, as people start adopting the explicit API, we can slowly move away from the implicit opt-outs entirely so that pages aren't unintentionally opting-out of bfcache's potential performance improvements?
Maybe we can have something like
history.disableBFCache()
? (thanks @annevk for suggesting this!)This might also be a good starting point into standardizing back-forward cache behavior across browsers. I'm not quite sure how much of the behavior is specced currently, but there certainly are some noticeable behavior difference between Firefox, Safari, and Chrome's implementation of bfcache (even in the opt-out signals, as mentioned above). I hope we can make the behavior more predictable and interoperable in the future :) - update: For other bfcache-related issues, see #5880. This thread will focus specifically on opt-out.
cc @annevk @smaug---- @mystor @cdumez @beidson @hober @altimin @xharaken @fergald
The text was updated successfully, but these errors were encountered: