WICG / nav-speculation

Proposal to enable privacy-enhanced preloading
https://wicg.github.io/nav-speculation/
Other
156 stars 35 forks source link

How to block storage access pre-activation? #7

Open domenic opened 4 years ago

domenic commented 4 years ago

For the reasons discussed in https://github.com/jeremyroman/alternate-loading-modes/blob/gh-pages/browsing-context.md, we need to block access to storage pre activation. There are at least two potential strategies for this:

  1. Block all storage access, as if the user were on an opaque origin. https://github.com/whatwg/storage/issues/18#issuecomment-615336554 discusses some of the spec mechanisms we'd use.

  2. Delay storage access, where possible. That is, synchronous storage access like localStorage and document.cookie would still need to be blocked. However, any asynchronous calls, like indexedDB.open(), could just have their promise or callback refuse to settle until activation.

  3. A variant of (2), where we don't just delay that particular call, but we freeze the entire document upon any such call. This could make it less likely for other tasks on the event loop to get confused by the hanging promise.

Additionally, all of these have a variant where we treat cookies differently from other types of storage. For cookies, we could give access to a partitioned cookie store pre-activation, and then merge it with the unpartitioned cookie store post-activation. This is possible for cookies, and not for other types of storage, because cookies have a very simple data model for which it's possible to write a reasonable merge algorithm.

domenic commented 4 years ago

This is possible for cookies, and not for other types of storage, because cookies have a very simple data model for which it's possible to write a reasonable merge algorithm.

@kinu I wrote this based on your comment in https://github.com/jeremyroman/alternate-loading-modes/pull/5#discussion_r512427639, but would you be able to expand on this point? For example, it seems like you'd still have conflicts with two same-name, different-value cookies. As another point, I wonder what the difference is between localStorage and cookies in this regard?

kinu commented 4 years ago

Thanks! Reg: the cookies cases: you're right that there still can be cases where conflicts happen. I was thinking about a bit more specific cases where the page has had no cookies, then partitioned == empty (== unpartitioned), and it feels there's less reason to let them fail.

There have been also some prior thoughts for starting with empty cookies and merging back changes based on timestamps on prerendering, i.e. https://www.chromium.org/developers/design-documents/cookies-and-prerender (option b and c)

It's a good point that document.cookies and localStorage have the very similar properties (they also have sync APIs). I'll think a bit more about this, but maybe they don't need to be distinguished.

jeremyroman commented 4 years ago

The idea of having localStorage throw but indexedDB hang is kind of weird and asymmetrical, so I suspect they should behave the same for consistency's sake. But maybe that's less of a big deal in practice.

domenic commented 3 years ago

We've had some more discussion of this issue in an external document, which analyzed it holistically with other pre-activation restrictions.

We feel like we have solid strategies for asynchronous storage APIs, BroadcastChannel, SharedWorker, and web locks.

What remains are:

nhiroki commented 3 years ago

Let me check my understanding. Based on the explanation in the external document, it's ok to grant both the sync and async storage APIs in prerendered pages as long as it is same-origin prerendering, right?

The current Chromium implementation and wpt_internal tests obey this assumption. If it's correct, I'll start upstreaming the tests.

domenic commented 3 years ago

Yes, that understanding is correct. No restrictions on same-origin prerendering.