Discuss: Removing `cache: reload` option from the API
Forcing a reload amplifies the timing signal in cache-based cross-origin leaks (see also http://sirdarckcat.blogspot.com/2019/03/http-cache-cross-site-leaks.html).
I'm filing this issue to discuss the trade-off. Is a control over the cache a granularity the web platform should have?
See also https://bugs.chromium.org/p/chromium/issues/detail?id=959789.
Even if we prevent cache: reload from being set by js I think the browser still needs to be able to set this value. For example, if the browser is triggering a reload because of something like ctrl-shift-r, then I think the FetchEvent.request.cache value should reflect that.
This would make the value similar to mode: navigate. Currently only the browser can set that mode, but its visible to script on FetchEvent.request.mode.
@wanderview: I agree! The change I was considering was related to the set of options that the cache attribute of the RequestInit argument to the fetch() API would accept, not to the underlying mechanism.
It might also be reasonable to allow CORS requests the ability to specify some of the alternative cache strategies, but we'd need to think through how they might allow attackers to evict cached resources they ought not have control over (e.g. evict only after a successful fetch?).
An attacker can add random query parameters (e.g., fetch(url + '&bogus=' + random_number, {mode: 'no-cors'})) to the target URL, which has a similar effect. I'm not sure how meaningful this protect would be.
@yutakahirano: Fetching url + random junk would end up evicting url + random junk from the cache, not url. The claim here is that some cache option values allow probing/evicting the cache state for a specific resource.
Ah, I see, thanks. Is this problem resolved by double-key caching?
Yes, for fetch() it would be resolved by that, as far as I know. (And I don't think we expose this functionality elsewhere.)
(We should probably open a separate issue on the exact shape of a double-key HTTP cache. I think that's our only viable complete solution here.)
Riffing on @yutakahirano's query parameters issue, if a response has a VARY header an attacker could request the url with a different set of matching request headers. I believe most http caches only store one entry per URL, so this would evict the target url as well. Kind of a corner case since it requires the response to use VARY, though.
I believe most http caches only store one entry per URL, so this would evict the target url as well.
Just browser caches.
So to be sure I understand correctly, is the proposal here that we'd add substep to step 14 of https://fetch.spec.whatwg.org/#dom-request to change cache mode to "default" if it's "reload"? Basically, if someone tampered with an existing reload request or created one themselves, we'd treat it as a normal request for the purposes of cache mode.
And I suppose some of the documentation might have to be clarified a bit.
Do we still care about this in a post-partitioning world?
@arturjanc might due to site-vs-origin?
I think there's still some value in doing this, partly because partitioning is not aligned with the same-origin policy: in browsers with double-keyed cache cross-site iframes share the cache partition with the embedder, and even triple-keyed cache has site and not origin-level granularity, so documents from the same site share will indeed share the partition.
That said, this behavior is mostly a convenience mechanism to invalidate the cache for a particular URL and if https://xsleaks.dev/docs/attacks/cache-probing/#invalidating-the-cache-with-errors is to be believed there are other known techniques to achieve this. Basically, I don't think fixing this will solve any XS-Leaks, it might just restrict same-partition attacks or require finding alternative cache eviction techniques -- so while it has non-zero positive value, it's probably not a super high-priority change.