whatwg / fetch

Fetch Standard
https://fetch.spec.whatwg.org/
Other
2.12k stars 333 forks source link

Add a way to have cookie origin and CORS origin be different #1637

Open npm1 opened 1 year ago

npm1 commented 1 year ago

Per https://github.com/fedidcg/FedCM/issues/428#issuecomment-1507543916, the FedCM API would like to have the following properties for its ID assertion fetch:

  1. The fetch uses the first-party identity provider cookies: this is needed for all relevant cookies to be available in order for the IDP to know which account to use.
  2. The fetch performs a CORS check against the API caller, which is the relying party. The relying party and the identity provider are different origins.

Our understanding is that there is currently no way to have the origin for (1) be different from the origin used for (2). But this seems to be required if we want to add a CORS check to this fetch. Let me know if I'm missing something, or any thoughts/ideas. Thanks!

annevk commented 1 year ago

We probably want to solve this as part of #693 and https://github.com/httpwg/http-extensions/issues/2084.

annevk commented 1 year ago

@arturjanc do you foresee any issues with including non-partitioned cookies on a cross-site request whose mode is "cors"? It would be a fairly novel type of request in the future and I could see intermediaries maybe getting confused?

arturjanc commented 1 year ago

My tl;dr is that using a credentialed CORS should be fine in this case, but it seems useful to discuss why.

Today, it's obviously possible to send credentialed cross-site CORS requests. In Chrome, this is allowed by default for SameSite=None cookies. In other browsers it's enabled via Storage Access API or if the user disables tracking protections (either per-site, or globally); in both cases it applies to default cookies (i.e. ones without a SameSite attribute).

In the future, I'd like to move to a model where you can't by default attach credentials to cross-site requests, except for top-level navigations made using safe methods or if a server opts into this on a per-endpoint basis. Even then, this would only apply to SameSite=None cookies. Of course this would have to still be bound by our privacy model -- it's not enough for the server to opt in to getting cross-site requests with cookies, there has to be some control that prevents such an opt-in from bypassing tracking restrictions.

For example, in cases that we've decided are okay from a tracking prevention perspective, e.g. if the user allows access to non-partitioned cross-site state using Storage Access API (or, more relevant to this bug, through the FedCM flow), I think CORS is the right mechanism for servers to signal opt-in to receive authenticated cross-site requests. Speculating a bit, my guess is that we'll want to strengthen the CORS model to require preflights for credentialed cross-origin/site POSTs (to remove the arguably strange loophole that allows Fetch to send POST requests without a preflight because that had already been possible through form#method=POST).

So, basically, from the FedCM perspective I don't think there's a problem with allowing these requests to be made in cors mode, both because it's not a security regression from the status quo and because it's compatible with the long-term cookie model we're aiming for.

arturjanc commented 1 year ago

One other thought that crossed my mind is that -- from the cookie model perspective -- while we generally want to allow credentialed cross-site CORS requests in the long term (under the conditions mentioned above), we want to reduce the number of situations where these requests are made with the POST method. This is because POST requests can trigger CSRF bugs; ideally, cross-site credentialed POSTs should require a CORS preflight, which means that owners of endpoints that rely on credentialed cross-origin POST requests will need to make these endpoints support preflights (which is likely a non-trivial change).

Here, we'll add a new case that sends authenticated cross-site POSTs, which might make locking down this pattern harder. I guess we could presumably exempt FedCM requests from preflight enforcement because they can only be made to URLs allowlisted in the FedCM manifest, but it's something we'll need to consider when we get to this.

domfarolino commented 1 year ago

to remove the arguably strange loophole that allows Fetch to send POST requests without a preflight because that had already been possible through form#method=POST

Here, we'll add a new case that sends authenticated cross-site POSTs, which might make locking down this pattern harder.

This is true. And separately, note that the FedCM ID assertion request does not trigger preflights by virtue of it happening to use the application/x-www-form-urlencoded request content type, thus using the "loophole" you mentioned earlier.

In any case, thanks for the detailed response @arturjanc!