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

Conversation

jyasskin
Copy link
Member

@jyasskin jyasskin commented Jun 5, 2020

Let me know if there are other side channels we're blocking.

README.md Outdated
@@ -105,16 +105,41 @@ 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.
Copy link
Collaborator

Choose a reason for hiding this comment

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

Interesting that this focuses on site over origin, but I guess it makes sense.

My understanding is that we're planning to block various channels for cross-origin portals. This might deserve a sentence or two.

Copy link
Member Author

Choose a reason for hiding this comment

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

Origins are mostly security boundaries, while sites are the privacy boundaries. My understanding of the goal is that: an origin's owner can opt into information passing between origins, but the end-user has to opt into information passing between sites. Obviously we're not entirely there yet.

Origins are more predictable than sites, so that could be a good reason to block cross-origin channels: to make it easier for developers to understand the restrictions. Is that why we're planning to block the cross-origin channels too, or is there an attack I've missed?

Copy link
Collaborator

Choose a reason for hiding this comment

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

My understanding of the goal is that: an origin's owner can opt into information passing between origins, but the end-user has to opt into information passing between sites. Obviously we're not entirely there yet.

This is probably reasonable, although I'll note that for largely architectural/implementation reasons we're trying to get rid of document.domain. (And I guess we're trying to get rid of cookies too?) So there might be a future where the end-user has to opt into information passing between origins.

Origins are more predictable than sites, so that could be a good reason to block cross-origin channels: to make it easier for developers to understand the restrictions. Is that why we're planning to block the cross-origin channels too, or is there an attack I've missed?

I think that's right. Plus the general program above of slowly trying to get rid of cross-origin same-site information sharing mechanisms means that we don't want to add any new ones.

README.md Show resolved Hide resolved
README.md Outdated
* [`postMessage()`](https://developer.mozilla.org/en-US/docs/Web/API/Window/postMessage) isn't allowed between a portal and its container.
* 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 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.
* Side channels:
* Portal Resize: Javascript outside the portal could use a sequence of portal resizes to send a user ID, so portals cannot be resized after creation.
Copy link
Collaborator

Choose a reason for hiding this comment

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

I believe the current model (discussed a bit in https://github.com/WICG/portals#rendering, which might deserve a cross-link) is that the containing page can resize the <portal> element as much as it wants, but this just causes the contents to get re-rasterized. The inner page does not know about the resizing; it is always painting into something that is the same size as the top-level tab.

I guess it's kind of unclear though, since that section still has "Discuss viewport size. Full viewport size at all times? Resizing OK or no? I'm sketchy on the plan here." Maybe we should take this opportunity to firm that up.

Copy link
Member Author

Choose a reason for hiding this comment

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

Good point: that was my mental model, but I didn't explain it well. I've written text that claims portals are scaled into the element, but I vaguely remember a desire to clip the portal contents sometimes instead of scaling it. Which is right?

@jeremyroman are you the right person to double-check this?

Copy link
Collaborator

Choose a reason for hiding this comment

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

Your current updates look pretty solid. I'd be comfortable merging as-is and revisiting when we write down the rescaling behavior in more precise detail (in #rendering).

README.md Outdated

#### Channels with 1 bit per user interaction

* User clicks a link, and the target site decides between a 204 or other non-navigating response, vs a real response, based on the user's id on the target site. This requires [specialized code on the target server](https://w3cping.github.io/privacy-threat-model/#cap-run-on-server), which allows [full user ID transfer](https://w3cping.github.io/privacy-threat-model/#model-cross-site-recognition) by other means.
Copy link
Collaborator

Choose a reason for hiding this comment

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

How exactly does this leak work? Is it via load events? Would it help if we only fired load events for the initial portal load, and not for any links being clicked inside the portal?

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'm arguing here that we don't need to fix this leak. But yes, it'd work via any "you can safely activate this portal now" event on the outer portal load. IIUC, you can't click links inside the portal since all interaction is blocked.

Copy link
Collaborator

Choose a reason for hiding this comment

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

I'm arguing here that we don't need to fix this leak. But yes, it'd work via any "you can safely activate this portal now" event on the outer portal load.

Hmm. I don't quite understand then. Could you outline the leak in more detail? What link is being clicked here, and how is that link related to a portal?

IUC, you can't click links inside the portal since all interaction is blocked.

True. I meant to discuss cases like JavaScript inside the portal doing location.href = "another-page.html" and that causes a load event. I believe that causes a load event for iframes.

Copy link
Member Author

Choose a reason for hiding this comment

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

Oooh, "clicks a link" is just wrong here. I meant to write about the page loading a portal and learning whether it's activatable, as discussed in #191 and #185. However, the fact that the initial load is done without credentials blocks this entirely, instead of just being "no worse than other mechanisms in the target platform". So ... I think I'll move this and the timing channel to the "blocked" list.

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.

README.md Outdated Show resolved Hide resolved
@jyasskin jyasskin force-pushed the flesh-out-privacy-considerations branch from 189df04 to 8a4801a Compare June 8, 2020 17:57
Mostly about being more precise about when restrictions are cross-site,
cross-origin, or same-origin.
@jyasskin jyasskin force-pushed the flesh-out-privacy-considerations branch from dd2fbe1 to 3512294 Compare June 8, 2020 18:11
README.md Outdated

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

* [`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.

README.md Outdated Show resolved Hide resolved
README.md Outdated Show resolved Hide resolved
Co-authored-by: Jake Archibald <jaffathecake@gmail.com>
Copy link
Collaborator

@jeremyroman jeremyroman left a comment

Choose a reason for hiding this comment

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

lgtm

README.md Outdated

* [`postMessage()`](https://developer.mozilla.org/en-US/docs/Web/API/Window/postMessage) isn't allowed between a cross-origin portal and its container.
* 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.

@domenic
Copy link
Collaborator

domenic commented Jun 16, 2020

Let's merge this :). Followup tweaks always welcome!

@domenic domenic merged commit 0e4b840 into WICG:master Jun 16, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants