Sending SameSite=Lax cookies for FedCM requests

30 views
Skip to first unread message

Christian Biesinger

unread,
Sep 16, 2025, 12:17:35 PMSep 16
to net-dev, Sam Goto
Hello net-dev,

(some context: https://github.com/w3c-fedid/FedCM/issues/587)

I had a previous discussion in chrome-security-owp about sending SameSite=Lax cookies for FedCM requests (including POST requests), and that group was satisfied with making that change.

Now I am looking at how to implement this and so I am asking this group for advice.

At a high-level, what I want is "if request->destination() == WebIdentity(), include SameSite=Lax cookies (in addition to SameSite=None)" (but do not send SameSite=Strict)

I believe this is the code to change:

But how should I get this information to this place?

I believe this is where the CookieOptions get created:

Some thoughts that occur to me:
- Add a boolean `force_allow_same_site_lax_cookies`, set it to true in that caller if destination==WebIdentity
- Override the SameSiteCookieContext::ContextType to SAME_SITE_LAX if destination==Webidentity
- Add the request destination to CookieOptions, check that in IncludeForRequestURL
- Something else?

Any advice?

Thanks!
Christian

Matt Menke

unread,
Sep 16, 2025, 12:24:31 PMSep 16
to Christian Biesinger, net-dev, Sam Goto
So the proposal is that any renderer process sending a fetch directly to /.well-known/webidentity would get to send samesite=lax cookies to the URL? I'm very much not a cookies person, but I'd be reluctant to add more capabilities for renderers to interact with 3P cookies. I thought the IDP code was mostly in the browser process?

--
You received this message because you are subscribed to the Google Groups "net-dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email to net-dev+u...@chromium.org.
To view this discussion visit https://groups.google.com/a/chromium.org/d/msgid/net-dev/CAPTJ0XGGPL0TBQUo_Asrqak-cTax84Mb4-xeNKk2r2pZH%2BCckg%40mail.gmail.com.

Christian Biesinger

unread,
Sep 16, 2025, 12:51:57 PMSep 16
to Matt Menke, net-dev, Sam Goto
No, that is not the proposal? I don't know where you got the renderer aspect from.

The well-known request is not credentialed; only the accounts endpoint and the ID assertion endpoint are.

I don't know if renderers can set the request destination arbitrarily; if they can, we should certainly disallow them setting it to WebIdentity. I want this, as you suggest, from the browser process.

Christian

Matt Menke

unread,
Sep 16, 2025, 12:59:27 PMSep 16
to Christian Biesinger, net-dev, Sam Goto
Renderers can request any URLs they want, that includes .well-know URLs. I had assumed you wanted to have net/ check the path because the caller didn't have privileges to configure requests itself.

If this isn't something we want renderers to do, then gating it on path doesn't make any sense - if we can't configure the URLLLoaderFactory/ResourceRequest to send lax cookies using current APIs (I'm not entirely clear on why we can't do that), then we should add a ResourceRequest::TrustedParam to do this, so that renderers can't use it.

On Tue, Sep 16, 2025 at 12:58 PM Matt Menke <mme...@chromium.org> wrote:
Renderers can request any URLs they want, that includes .well-know URLs. I had assumed you wanted to have net/ check the path because the caller didn't have privileges to configure requests itself.

If this isn't something we want renderers to do, then gating it on path doesn't make any sense - if we can't configure the URLLLoaderFactory/ResourceRequest to send lax cookies using current APIs (I'm not entirely clear on why we can't do that), then we should add a ResourceRequest::TrustedParam to do this, so that renderers can't use it.

Christian Biesinger

unread,
Sep 16, 2025, 1:23:57 PMSep 16
to Matt Menke, net-dev, Sam Goto
I don't understand why you are talking about URLs. By destination, I meant the RequestDestination enum, not the URL, like I said.

The reason why I can't configure the loader to make this work (as far as I can tell) is that SameSite=Lax cookies never get sent in POST requests so there is no way to make that happen without changing net code.

Christian

On Tue, Sep 16, 2025 at 12:58 PM Matt Menke <mme...@chromium.org> wrote:
Renderers can request any URLs they want, that includes .well-know URLs. I had assumed you wanted to have net/ check the path because the caller didn't have privileges to configure requests itself.

If this isn't something we want renderers to do, then gating it on path doesn't make any sense - if we can't configure the URLLLoaderFactory/ResourceRequest to send lax cookies using current APIs (I'm not entirely clear on why we can't do that), then we should add a ResourceRequest::TrustedParam to do this, so that renderers can't use it.

Matt Menke

unread,
Sep 16, 2025, 1:39:16 PMSep 16
to Christian Biesinger, net-dev, Sam Goto
Sorry, missed that (And focused on your question why I was talking about URLs). If renderers can set destinations without restrictions, I don't think we want to tie sending SameSite=Lax cookies to something that could be set arbitrarily by a compromised renderer. If we do restrict destinations we accept from renderers, though, that could be an option.

Interesting that we don't send SameSite=Lax cookies on POSTs. I assume that's just on cross-origin navigations that are POSTs - subresource POSTs we presumably do, but also send SameSite=Strict cookies.

Maksim Orlovich

unread,
Sep 16, 2025, 1:45:12 PMSep 16
to Christian Biesinger, net-dev, Sam Goto
On Tue, Sep 16, 2025 at 12:17 PM Christian Biesinger <cbies...@chromium.org> wrote:
Hello net-dev,

(some context: https://github.com/w3c-fedid/FedCM/issues/587)

I had a previous discussion in chrome-security-owp about sending SameSite=Lax cookies for FedCM requests (including POST requests), and that group was satisfied with making that change.

Now I am looking at how to implement this and so I am asking this group for advice.

At a high-level, what I want is "if request->destination() == WebIdentity(), include SameSite=Lax cookies (in addition to SameSite=None)" (but do not send SameSite=Strict)

I believe this is the code to change:

But how should I get this information to this place?

I believe this is where the CookieOptions get created:

Rather one statement above --- ComputeSameSiteContextForRequest is what's supposed to figure it out. It is not a pretty family of functions functions, and making it more complicated will not make anyone happy, but putting magical logic outside it would probably make things worse (also it has other callers).


Christian Biesinger

unread,
Sep 16, 2025, 2:15:10 PMSep 16
to Maksim Orlovich, net-dev, Sam Goto
@mmenke yes, sorry, I was of course only referring to cross-site requests. It is interesting to me that compromised renderers can (apparently) set any destination they want, that seems to rather reduce the "sec" part of the "sec-fetch-dest" header. Do you know where I should look if I wanted to implement such a restriction?

@maksim If I understand you correctly, what you are suggesting is to pass in the RequestDestination to ComputeSameSiteContextForRequest and return SAME_SITE_LAX for kWebIdentity requests?

Thanks,
Christian

Matt Menke

unread,
Sep 16, 2025, 2:21:37 PMSep 16
to Christian Biesinger, Maksim Orlovich, net-dev, Sam Goto
CorsURLLoaderFactory::IsValidRequest() is where we do almost all our request validation. Despite the name, it's applied to all requests that don't originate within the network stack, even ones with a cors mode of none.

--
You received this message because you are subscribed to the Google Groups "net-dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email to net-dev+u...@chromium.org.

Christian Biesinger

unread,
Sep 16, 2025, 5:22:07 PMSep 16
to Matt Menke, Maksim Orlovich, net-dev, Sam Goto
Hi Matt and Maksim,

Thanks for your help so far; https://crrev.com/c/6954729 is in the CQ to only allow the browser process to use destination==kWebIdentity. There may be other destinations that should be browser-only, but I am not familiar with them so I only did this for WebIdentity.

But it seems that URLRequest does not have access to the RequestDestination that was set on the ResourceRequest. Do you have any advice for how to access this data from URLRequestHttpJob?

Thanks,
Christian

Matt Menke

unread,
Sep 16, 2025, 5:24:27 PMSep 16
to Christian Biesinger, Maksim Orlovich, net-dev, Sam Goto
net/ largely is an implementation of HTTP, while RequestDestination is a web-platform concept, so doesn't really belong in net/, so we should avoid introducing net/ dependencies on the class (or moving it to net/, since net/ can't depend on services/network). I defer to folks who know more about cookies on the details, but presumably we should introduce some way for services/network to inject some hopefully more general information into the cookie code, either through a callback (in NetworkDelegate or URLRequestDelegate) or by yet another field in URLRequest.

Christian Biesinger

unread,
Oct 7, 2025, 3:46:42 PMOct 7
to Matt Menke, Maksim Orlovich, net-dev, Sam Goto
So, I figured out one way of doing this: https://chromium-review.googlesource.com/c/chromium/src/+/7017375

This works, as indicated by external/wpt/fedcm/fedcm-same-site-none.https.html failing. But would something like this be acceptable?

If not, could you advise a better way of doing this?

Thanks!
Christian

Matt Menke

unread,
Oct 7, 2025, 3:55:54 PMOct 7
to Christian Biesinger, Maksim Orlovich, net-dev, Sam Goto
That's a good question. We do have prior art at the cache layer for pulling information from request headers, though in this case, the header was set by the network process, so we could push the value without doing the (not cheap, but not the end of the world) header search and string copies. I do feel that someone more familiar with cookies would be better situated to make decisions about the API here. I guess the extra logic is needed because webidentity uses posts, which isn't considered a safe method? Is there a spec with this proposed behavior change? Not pushing back, just hoping for standardization, and I think having a spec might better inform the API shape.

Christian Biesinger

unread,
Oct 7, 2025, 4:03:24 PMOct 7
to Matt Menke, Maksim Orlovich, net-dev, Sam Goto
I don't have a spec draft yet, but I was pointed to this section of the fetch spec: https://fetch.spec.whatwg.org/#determine-the-same-site-mode

Presumably I would insert a new step before (3) saying something like "If request's destination is webidentity, return lax-or-less". But this is a fetch layer, so higher than this code is right now...

Christian

Matt Menke

unread,
Oct 7, 2025, 4:40:29 PMOct 7
to Christian Biesinger, Maksim Orlovich, net-dev, Sam Goto
So the options I see are (skipping over some even more minor variants):

1) Pull string from headers, hard code list of special destinations in net/cookies/.
2) Move destination enum into net/, set it on URLRequest, hard code list of special destinations in net/cookies/.
3) Set a magic bit on URLRequest (using a hard-coded list of special destinations in services/network) to allow Same-Site-Lax cookies for untrusted destinations, have the URLRequestHttpJob pull out the bit and send it to net/cookies.
4) Like 3, but add a URLRequest::Delegate method to pull out the bool. This isn't how things generally work in URLRequestDelegate, so 3) seems more consistent with current API design.

I'd prefer 3), just to avoid having the list of special-cased (or any) destination types in net/, though perhaps I'm being too much of a purist. I don't have my heart set on that approach, though. Open to other ideas/opinions.

Christian Biesinger

unread,
Oct 9, 2025, 5:21:17 PMOct 9
to Matt Menke, Maksim Orlovich, net-dev, Sam Goto
Hi Matt,

Something like this? https://crrev.com/c/7017375
I did notice there's already other force-cookie-related properties on URLRequest so I added this one nearby.

(There's also option 5, let the consumer (the FedCM code in content/browser/webid) set the force-allow-lax bit on ResourceRequest and pass it through, and validate that only the browser process can set it, but that's probably worse?)

Christian

Matt Menke

unread,
Oct 9, 2025, 5:27:34 PMOct 9
to Christian Biesinger, Maksim Orlovich, net-dev, Sam Goto
On Thu, Oct 9, 2025 at 5:11 PM Christian Biesinger <cbies...@chromium.org> wrote:
Hi Matt,

Something like this? https://crrev.com/c/7017375
I did notice there's already other force-cookie-related properties on URLRequest so I added this one nearby.

Yes, exactly something like that. Should we consider clearing the bit on cross-origin redirects?

(There's also option 5, let the consumer (the FedCM code in content/browser/webid) set the force-allow-lax bit on ResourceRequest and pass it through, and validate that only the browser process can set it, but that's probably worse?)

My experience has been that if you provide a public API, folks often start using it in ways that are probably not a great idea, so unless/until we discover a greater need for it, yea, I'd prefer not to add a bit to ResourceRequest. If we ever do, though, I'd prefer it to be on ResourceRequest::TrustedParams, so it's not renderer-exposed.

Christian Biesinger

unread,
Oct 20, 2025, 2:03:38 PMOct 20
to Matt Menke, Maksim Orlovich, net-dev, Sam Goto
On Thu, Oct 9, 2025 at 5:27 PM Matt Menke <mme...@chromium.org> wrote:
On Thu, Oct 9, 2025 at 5:11 PM Christian Biesinger <cbies...@chromium.org> wrote:
Hi Matt,

Something like this? https://crrev.com/c/7017375
I did notice there's already other force-cookie-related properties on URLRequest so I added this one nearby.

Yes, exactly something like that. Should we consider clearing the bit on cross-origin redirects?

Just realized I never replied to this email. We disable redirects for these requests, so from my perspective the answer to this question doesn't matter.
https://crrev.com/c/7017375 is ready for review.
 

(There's also option 5, let the consumer (the FedCM code in content/browser/webid) set the force-allow-lax bit on ResourceRequest and pass it through, and validate that only the browser process can set it, but that's probably worse?)

My experience has been that if you provide a public API, folks often start using it in ways that are probably not a great idea, so unless/until we discover a greater need for it, yea, I'd prefer not to add a bit to ResourceRequest. If we ever do, though, I'd prefer it to be on ResourceRequest::TrustedParams, so it's not renderer-exposed.

Makes sense.

Christian
Reply all
Reply to author
Forward
0 new messages