Skip to content
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

Flesh out the privacy threat model. #208

Merged
merged 6 commits into from
Jun 16, 2020
Merged
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
31 changes: 25 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -107,16 +107,35 @@ The general idea of portals is summed up above: inset pre-rendering, activation,

### Privacy threat model and restrictions

The Portals design 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 Portals and how the design satisfies them.

A portal can contain either a same-site or cross-site resource. Same-site portals 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 portals.

This design assumes that storage will be [partitioned](https://github.com/privacycg/storage-partitioning), even though that is not the status quo in all browsers. Because portaled documents can be activated into a top-level browsing context, they (eventually) live in the first-party storage partition of their origin. This means we have to prevent communication with the surrounding document to the same extent we prevent it with a cross-site link opened in a new tab.
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Are we going to follow the lead of partitioning here, or might we come up with a simpler system like "no storage until activation" rather than partition?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I meant this to be compatible with "no storage until activation", as the partitioning explainer anticipates that some storage will be blocked from a third-party context: privacycg/storage-partitioning#8. The "(eventually)" hints at this, but I wonder if you have an idea for being clearer about it, without using lots of words?

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not sure I can do fewer words, but maybe:

This design assumes that storage will be partitioned/blocked in line with the browser's implementation (or lack thereof) of storage-partitioning.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've added "or blocked" to try to capture this. How's the new text?


#### Channels that are blocked
domenic marked this conversation as resolved.
Show resolved Hide resolved

* [`postMessage()`](https://developer.mozilla.org/en-US/docs/Web/API/Window/postMessage) isn't allowed between a cross-origin portal and its container.
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The use of "cross-origin" in this line makes it sound like it might be an exception to this from above:

For simplicity, when a cross-site channel needs to be blocked, we also block it for same-site cross-origin portals.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is an example of the above: it only truly needs to be blocked for cross-site portals, but we're also blocking it for same-site cross-origin portals.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe just:

  • postMessage() isn't allowed between a portal and its container.

…removing "cross-origin", because it's implied above?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There are some restrictions below that that apply to same-origin portals, and I wanted to be clear which was which. I feel like "isn't allowed between a portal and its container" reads like it applies to same-origin portals too, which isn't the case.

* Blocked by preventing fetches within portals from using credentials until they're activated:
* The sequence of portal loads: The source page can encode its user ID into the order in which a sequence of URLs are loaded into portals. To prevent the target from correlating this ID with its own user ID without a navigation, documents loaded into cross-origin portals are fetched without credentials and don't have access to either first-party storage or multi-keyed storage. They have to use [`requestStorageAccess()`](https://developer.mozilla.org/en-US/docs/Web/API/Document/requestStorageAccess) (or another TBD mechanism) to get access while they're being activated.
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: I'd probably say "when they're activated" (as it seems to me like an instant event as opposed to a duration/state)

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done.

* The site creates a portal, and the target site decides between a 204 and a real response based on the user's ID. Or the site delays the response by an amount of time that depends on the user's ID. Because the portal load is done without credentials, the site can't get its user ID in order to make this sort of decision.
* Side channels, further discussed in [Rendering](#rendering):
* Portal Resize: JavaScript outside the portal could use a sequence of portal resizes to send a user ID, so a portal's content cannot observe any resizes after creation. If a portal is resized, that just rescales the view of the portal. For simplicity, this is the case for same-origin portals too.
* Portal initial size: JavaScript outside the portal could use the initial size to send part of a user ID, so portals are always sized the same as the top-level tab that they'll be activated into and then scaled into the portal element. For simplicity, this is the case for same-origin portals too.
* Intersection Observer: Won't give visibility information to script inside the portal, to avoid occlusion being used to send information.
* [Page Visibility](https://developer.mozilla.org/en-US/docs/Web/API/Page_Visibility_API) and the timing of `requestAnimationFrame()` callbacks match the visibility of the top-level page, as in iframes, to prevent the page from encoding messages in visibility changes. However, this leads to the possibility that a portal and containing page could use the timing of user-caused visibility changes to join the user across site boundaries. Whether and how to prevent this is [still under discussion](https://github.com/WICG/portals/issues/193#issuecomment-639768218).

#### Channels that match navigation

* The URL of the activated portal and the referring URL are available to normal navigations to the same extent they're available to a portal. Solutions to link decoration will apply to both.


TODO:

- Privacy threat model summary and goals. Focused on cross-origin threats.
- Storage and communication restrictions summary
- Brief discussion of side channels
- Discuss pre-activation vs. post-activation, `requestStorageAccess()`, ...
- More side channels?
- Maybe this is also the place to discuss the fact that there's no sync access (even same-origin)?
- Discuss "the origin model" explicitly. This uses the normal origin model (like iframes), but with restrictions similar to those already in place elsewhere in the platform (such as restricted storage).
- This section might benefit from being split in two.
- Note that design-discussions.md has a lot of stuff that might be useful here, and should probably be deleted if we're going to cover it here. (Or, we could keep using it as a place to put more details, and link to it from here.)
- Note that design-discussions.md has discussion about hiding never-activated portals from their servers, which is a different sort of attack than the cross-site tracking we discuss here.

### Permissions and policies

Expand Down