Skip to content

Commit

Permalink
Support same-site cross-origin prerendering
Browse files Browse the repository at this point in the history
This includes our first formal spec for Supports-Loading-Mode, and an update to its explainer to reflect what we're most immediately looking to ship.
  • Loading branch information
domenic authored Sep 2, 2022
1 parent a523bc4 commit 16570ff
Show file tree
Hide file tree
Showing 9 changed files with 175 additions and 110 deletions.
6 changes: 3 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,20 +21,20 @@ See [the full explainer](./triggers.md) for more.

Prerendering is more complex than prefetching, as it involves running the target page's scripts and loading its subresources. We've produced a couple of relevant explainers:

* [Same-origin prerendering](./prerendering-same-origin.md), discusses what we believe to be solid so far: user agent-triggered and same-origin-triggered prerendering.
* [Same-site prerendering](./prerendering-same-site.md), discusses what we believe to be solid so far: user agent-triggered and same-site-triggered prerendering.
* [Prerendering state APIs](./prerendering-state.md), discussing the new `document.prerendering` API and its associated event in more detail.

## Cross-origin and cross-site concerns

Much of the complexity of preloading comes in when dealing with site that is cross-origin or cross-site. Origins are the web's security boundary, and sites are its privacy boundary, so any preloading across these boundaries needs to preserve the relevant properties.

Our current proposals are focused around allowing cross-origin/site prefetching. We also have some early thoughts on cross-origin/site prerendering, but have not yet committed to them. The following explainers are relevant:
Our current proposals are focused around allowing cross-origin/site prefetching, and cross-origin but same-site prerendering. We also have some early thoughts on cross-site prerendering, but have not yet committed to them. The following explainers are relevant:

* [Cross-site preloading fetching modes](./fetch.md), discussing how to perform the fetch of the main content and any subresources while doing cross-site preloading.
* [`Supports-Loading-Mode`](./opt-in.md), a new header which allows target pages to opt in to being loaded in an uncredentialed mode, with the understanding that they will upgrade their content later upon activation.
* [`<meta http-equiv="supports-loading-mode">`](https://github.com/WICG/nav-speculation/blob/main/meta-processing.md), an extension to the header definition that uses a HTML preparsing pass to allow it to appear in-document.
* [Client IP anonymization](./anonymous-client-ip.md), an extension to prefetching (and maybe one day prerendering?) to require using an anonymizing proxy to hide the user's IP address.
* [Cross-origin prerendering](./cross-origin-prerendering.md), containing what we've brainstormed so far about how cross-origin prerendering could work in the future.
* [Cross-site prerendering](./cross-site-prerendering.md), containing what we've brainstormed so far about how cross-site prerendering could work in the future.

## Portals

Expand Down
155 changes: 79 additions & 76 deletions opt-in.md

Large diffs are not rendered by default.

16 changes: 8 additions & 8 deletions prerendering-cross-origin.md → prerendering-cross-site.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# Cross-origin prerendering
# Cross-site prerendering

Building on our vision for [same-origin prerendering](./prerendering-same-origin.md), we would eventually like to enable prerendering of cross-origin content.
Building on our vision for [same-site prerendering](./prerendering-same-site.md), we would eventually like to enable prerendering of cross-site content.

None of this is implemented or specified in detail yet. But, we've spent some time thinking about it, and wanted to capture that process publicly.

Expand All @@ -18,11 +18,11 @@ None of this is implemented or specified in detail yet. But, we've spent some ti

## Privacy-based restrictions

In addition to the [restrictions for same-origin prerendering](./prerendering-same-origin.md#restrictions), cross-origin prerendering has more privacy-based restrictions. In particular, prerendering is intended to comply with the [W3C Target Privacy Threat Model](https://w3cping.github.io/privacy-threat-model/). This section discusses the aspects of that threat model that are particularly relevant to the browsing context part of the story, and how the design satisfies them.
In addition to the [restrictions for same-site prerendering](./prerendering-same-site.md#restrictions), cross-site prerendering has more privacy-based restrictions. In particular, prerendering is intended to comply with the [W3C Target Privacy Threat Model](https://w3cping.github.io/privacy-threat-model/). This section discusses the aspects of that threat model that are particularly relevant to the browsing context part of the story, and how the design satisfies them.

A prerendering browsing context can contain either a same-site or cross-site resource. Same-site prerendered content don't present any privacy risks, but cross-site resources risk enabling [cross-site recognition](https://w3cping.github.io/privacy-threat-model/#model-cross-site-recognition) by creating a messaging channel across otherwise-partitioned domains. For simplicity, when a cross-site channel needs to be blocked, we also block it for same-site cross-origin content. In some cases we even block it for same-origin content.

Because prerendered browsing contexts can be activated, they (eventually) live in the first-party [storage shelf](https://storage.spec.whatwg.org/#storage-shelf) of their origin. This means that the usual plan of [storage partitioning](https://github.com/privacycg/storage-partitioning) does not suffice for prerendering browsing contexts as it does for nested browsing contexts (i.e. iframes). Instead, we take the following measures to restrict cross-origin prerendered content:
Because prerendered browsing contexts can be activated, they (eventually) live in the first-party [storage shelf](https://storage.spec.whatwg.org/#storage-shelf) of their origin. This means that the usual plan of [storage partitioning](https://github.com/privacycg/storage-partitioning) does not suffice for prerendering browsing contexts as it does for nested browsing contexts (i.e. iframes). Instead, we take the following measures to restrict cross-site prerendered content:

- Prevent communication with the referring document, to the same extent we prevent it with a cross-site link opened in a new tab.
- Block all storage access while content is prerendered.
Expand All @@ -35,11 +35,11 @@ The below subsections explore the implementation of these restrictions in more d

### Storage access blocking

Prerendered pages that are cross-origin to their referring site will have no access to storage.
Prerendered pages that are cross-site to their referring site will have no access to storage.

We could attempt to address the threat by providing partitioned or ephemeral storage access, but then it is unclear how to transition to _unpartitioned_ storage upon activation. It would likely require some kind of web-developer-written merging logic. Completely blocking storage access is thus deemed simpler; prerendered pages should not be doing anything which requires persistent storage before activation.

This means that most existing content will appear "broken" when prerendered by a cross-origin referrer. This necessitates an explicit opt-in to allow cross-origin content to be prerendered, [discussed elsewhere](./opt-in.md). Such content might optionally "upgrade" itself to a credentialed view upon activation, as shown in the [example](#example) above.
This means that most existing content will appear "broken" when prerendered by a cross-site referrer. This necessitates an explicit opt-in to allow cross-site content to be prerendered, [discussed elsewhere](./opt-in.md). Such content might optionally "upgrade" itself to a credentialed view upon activation, as shown in the [example](#example) above.

For a more concrete example, consider `https://aggregator.example/` which wants to prerender this GitHub repository. To make this work, GitHub would need to add the opt-in to allow the page to be prerendered. Additionally, GitHub should add code to adapt their UI to show the logged-in view upon activation, by removing the "Join GitHub today" banner, and retrieving the user's credentials from storage and using them to replace the signed-out header with the signed-in header. Without such adapter code, activating the prerendering browsing context would show the user a logged-out view of GitHub in the top-level tab that the prerendering browsing context has been activated into. This would be a bad and confusing user experience, since the user is logged in to GitHub in all of their other top-level tabs.

Expand All @@ -56,8 +56,8 @@ As for the exact mechanism of this blocking:
- `SharedWorker` construction is delayed in prerendering browsing contexts. In particular, while the `new SharedWorker()` constructor returns immediately, no worker is started or connected to until after activation. Any messages sent to the `SharedWorker` pre-activation are buffered up and delivered upon activation. (And, since the `SharedWorker` is not connected to an actual shared worker pre-activation, no message can be received on it pre-activation.)
- Web locks APIs will return promises which wait to settle (and wait to do any lock-related work) until activation.
- TODO `ServiceWorker`?
- Fetches within cross-origin prerendering browsing contexts, including the initial request for the page, do not use credentials. Credentialed fetches could be used for cross-site recognition, for example by:
- Using the sequence of loads. The referring page could encode a user ID into the order in which a sequence of URLs are prerendered. To prevent the target from correlating this ID with its own user ID without a navigation, a document loaded into a cross-origin prerendering browsing context is fetched without credentials and doesn't have access to storage, as described above.
- Fetches within cross-site prerendering browsing contexts, including the initial request for the page, do not use credentials. Credentialed fetches could be used for cross-site recognition, for example by:
- Using the sequence of loads. The referring page could encode a user ID into the order in which a sequence of URLs are prerendered. To prevent the target from correlating this ID with its own user ID without a navigation, a document loaded into a cross-site prerendering browsing context is fetched without credentials and doesn't have access to storage, as described above.
- The host creates a prerendering browsing context, and the prerendered site decides between a 204 and a real response based on the user's ID. Or the prerendered site delays the response by an amount of time that depends on the user's ID. Because the prerendering load is done without credentials, the prerendered site can't get its user ID in order to make this sort of decision.
- Sizing side channels: prerendering browsing contexts always perform layout based on the initial size of their referring browsing context, as its most likely that upon activation, they'll end up with that same size. However, further resizes to the referring browsing context are not used to update the size of the prerendering browsing context, as this could be used to communicate a user ID. For simplicity, we apply this sizing model to same-origin prerendered content as well.

Expand Down
Loading

0 comments on commit 16570ff

Please sign in to comment.