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

Fetch-Metadata to indicate when the browser is in a partitioned context #80

Open
DCtheTall opened this issue Nov 16, 2021 · 15 comments
Open

Comments

@DCtheTall
Copy link
Member

The problem

To improve privacy on the web, browsers are partitioning their cookie jars by first-party context. Chrome is planning on blocking (unpartitioned) third-party cookies by default. Browsers are only exposing state to third-parties that is partitioned by top-level site. CHIPS proposes that servers use the Set-Cookie header to set cross-site, Partitioned cookies which can still be sent in cross-site contexts. Firefox’s Total Cookie Protection feature also partitions all third-party cookies by default.

Servers will need to serve clients that may or may not partition third-party cookies. This could be older clients that support unpartitioned third-party cookies, or even newer clients. It would be helpful for site developers if their servers received some signal that user agents are sending requests from a partitioned context, especially during this transitory time when the web is phasing out unpartitioned cross-site (i.e. third-party) cookies.

Proposed solution

Part of the existing Fetch Metadata proposal includes a new header, Sec-Fetch-Site, an enum whose value can be same-origin, same-site, or cross-site. This header can indicate to servers that the request is coming from a cross-site context, but not if the current user agent is in a partitioned embedded context. One possible solution is to add a variant to this enum, cross-site-partitioned, and have it be sent by clients which partition embedded third-party contexts by top-level site. One con of this particular scheme is that some servers may use Sec-Fetch-Site: cross-site for logic used for security decisions.

Another option would be to add a new request header, Sec-Partitioned: ?1 or Sec-Partitioned-Context: ?1, which is only sent when the request is coming from a partitioned context. One difference between this option and the former design is that this header could also provide a signal to the top-level site that the user agent is in a partitioned context as well, if that signal is useful for them.

@annevk suggested this as a possible approach in WICG/CHIPS/issues/2.

cc / @krgovind

@annevk
Copy link
Member

annevk commented Nov 17, 2021

As I mentioned there I think we might want something that addresses this and #56 together. I also believe that Chrome's approach around partitioning has shifted somewhat to consider A2 in A1 -> B -> A2 to be partitioned.

The main worry I have with a boolean is that you will then still need the other information to determine what your partition key actually is. (Though also see privacycg/storage-partitioning#14 for why exposing that in detail is not necessarily desirable either.)

cc @wanderview

@mikewest
Copy link
Member

How does this differ from the Sec-Fetch-Ancestors proposal that Anne pointed to? If that can be tweaked to serve your need, I'd rather ship it, as it's an explanation of SameSite cookie behavior that's missing today.

@krgovind
Copy link

While it is true that the storage partitioning key being proposed for Chromium would consider A1 -> B -> A2 to be partitioned; the proposed partitioning approach for cookies would not treat A1 -> B -> A2 as partitioned. As the explainer describes, the partition key is only comprised of the top-level document's site (or First-Party Set owner if the site is in an FPS).

My understanding is that with the storage partitioning approach, we are trying to address the interaction of SameSite=Lax|Strict cookies with service workers. However, partitioned cookies only work in conjunction with SameSite=None cookies and do not need to consider the ancestor chain.

I do think the requirements for partitioned cookies are slightly different from what is being proposed for Sec-Fetch-Ancestors:

  • A1 -> B -> A2 and B -> A2 are both Sec-Fetch-Ancestors: cross-site; but the first is Sec-Partitioned: 0 and the second is Sec-Partitioned: 1
  • If I'm understanding correctly, Sec-Fetch-Ancestors would not indicate whether the client performed state partitioning or not. We are proposing this header to allow servers to disambiguate between clients that do/don't partition state even in cross-site contexts. (e.g. a client may decide not to partition some cross-site contexts due to enterprise policy, or user configuration)
@annevk
Copy link
Member

annevk commented Nov 18, 2021

So that would mean that you get partitioned IndexedDB but unpartitioned cookies in A2 (assuming they use SameSite=None)? Isn't that rather confusing for web developers? (And the Sec-Partitioned header would only explain one of those, which I'd argue is also quite confusing.)

@annevk
Copy link
Member

annevk commented Nov 18, 2021

If we cannot reconcile these I think Sec-Fetch-Ancestors should express both relationships. That in A1 -> B -> A2, A2 is cross-site to A1 as well as same-origin for SameSite=None cookie purposes.

@dveditz
Copy link
Member

dveditz commented Nov 22, 2021

If a browser goes to the trouble of partitioning cookies for privacy reasons does it really want to reveal that fact to the websites? Not quite the same thing, but Firefox's "Containers" feature is supposed to make different containers appears as completely separate browser instances to web sites. What benefit does this proposal offer to privacy-concerned users?

@krgovind
Copy link

If a browser goes to the trouble of partitioning cookies for privacy reasons does it really want to reveal that fact to the websites?

This behavior is supposed to be enabled for all users; as opposed to an opt-in mode (like Container Tabs). The intention here is to allow sites to detect and adapt to the new default behavior for compatibility reasons.

Not quite the same thing, but Firefox's "Containers" feature is supposed to make different containers appears as completely separate browser instances to web sites. What benefit does this proposal offer to privacy-concerned users?

I think the main difference from Containers is that browsers are proposing to now make each new top-level site within the same tab/profile a separate "container tab"/"partition". For example, websites may have embedded login buttons on sites that perform top-level redirects for authentication, and redirect back to the original page. This type of flow has depended on access to unpartitioned cross-site cookies, and will break in the "partitioned by-default" world.

@dveditz
Copy link
Member

dveditz commented Nov 22, 2021

Isn't that the exact problem addressed by the Storage Access API ?

@krgovind
Copy link

krgovind commented Nov 22, 2021

For many use-cases, websites can make do with partitioned state. I think we should enable sites to make that migration as much as possible. Storage Access API's usage should be restricted to cases that really cannot make do with partitioned state.

Edit: I should also clarify that Chrome currently does not ship Storage Access API. We are investing in more focused solutions at this time.

@annevk
Copy link
Member

annevk commented Nov 23, 2021

I don't think the comparison with Firefox Containers is useful here. Containers enables browsers-within-a-browser. Partitioning isolates cross-site website state within a single top-level site within a browser (or container, if you will). Revealing to a cross-site website that it is partitioned mostly reveals that it is cross-site, a fact it can often obtain through other means already. I'd classify this mostly as an ergonomics feature for web developers.

@krgovind
Copy link

If we cannot reconcile these I think Sec-Fetch-Ancestors should express both relationships.

@annevk On the Chrome side, we are looking into whether it's possible to reconcile or not.

That in A1 -> B -> A2, A2 is cross-site to A1 as well as same-origin for SameSite=None cookie purposes.

But in the meantime, I thought it might be worth exploring this direction. "[...] same-origin for SameSite=None cookie purposes." doesn't quite sound right since SameSite=None cookies don't need the context to be same-origin, or even same-site. Maybe we just add a token like partitioned|unpartitioned? I realize this is defining a new concept, but I think that's needed since this is distinct from same-site/same-origin.

@annevk
Copy link
Member

annevk commented Nov 23, 2021

Why don't SameSite=None cookies need to be same-site with the top-level? Wouldn't you get different cookies otherwise?

@krgovind
Copy link

Perhaps you are conflating SameSite's CSRF protections with third-party/partitioning behavior? SameSite=None cookies as per current definition in RFC6265bis can be sent in cross-site contexts. SameSite=Strict|Lax need the entire ancestor chain to be same-site. As long as unpartitioned third-party cookies are supported; SameSite=None cookies will get the same cookie value in all contexts (regardless of top-level site). On browsers where unpartitioned 3p cookies are being blocked, SameSite=None cookies will simply be blocked when the request is cross-site with the top-level. (This is my understanding of the expected behavior across Chrome, Firefox, and Safari anyway)

With the CHIPS explainer, we are proposing that if developers add the Partitioned attribute in conjunction with SameSite=None, they won't be blocked, but will received a different value per partitioned-context. e.g. You may consider "A2" and "A1 -> B -> A2" as the same partition; but "B -> A2" and "C -> A2" would be different partitions.

@annevk
Copy link
Member

annevk commented Nov 23, 2021

The precondition for CHIPS is that cross-site cookies are blocked. That raises the question of what cross-site is. It seems that for A1 -> B -> A2 there are different definitions. That's what I was trying to express. (We might also want to consider script access here.)

@krgovind
Copy link

The precondition for CHIPS is that cross-site cookies are blocked.

Actually, since CHIPS needs developer opt-in; that is not a precondition. We are proposing that even if unpartitioned third-party (i.e. request is to a URL that is cross-site to the top-level document) cookies are supported on the client; we will partition cookies that are labeled with the Partitioned attribute. This is to allow websites to prepare to transition to the partitioned-by-default world in advance.

That raises the question of what cross-site is. It seems that for A1 -> B -> A2 there are different definitions. That's what I was trying to express. (We might also want to consider script access here.)

I'm not sure if we have a canonical definition of cross-site, but as per RFC6265bis the request to A2 in A1 -> B -> A2 is considered cross-site.

This is why I'm wondering if we need to define a new concept to avoid confusion with the 6265bis definition?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
5 participants