-
Notifications
You must be signed in to change notification settings - Fork 66
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
Flesh out the privacy threat model. #208
Conversation
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. |
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
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?
There was a problem hiding this comment.
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
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. |
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
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?
There was a problem hiding this comment.
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. |
There was a problem hiding this comment.
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?
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done.
189df04
to
8a4801a
Compare
Mostly about being more precise about when restrictions are cross-site, cross-origin, or same-origin.
dd2fbe1
to
3512294
Compare
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. |
There was a problem hiding this comment.
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?
There was a problem hiding this comment.
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?
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
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. |
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
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?
There was a problem hiding this comment.
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.
Co-authored-by: Jake Archibald <jaffathecake@gmail.com>
There was a problem hiding this 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. |
There was a problem hiding this comment.
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)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done.
Let's merge this :). Followup tweaks always welcome! |
Let me know if there are other side channels we're blocking.