Skip to content

Why Sec-FedCM-CSRF and not Sec-Fetch-Mode #320

Closed

Description

@martinthomson

Sec-Fetch-Mode seems purpose-built for this sort of thing. Adding another header field doesn't really help a lot.

(A server will naturally ignore either a new Sec-Fetch-Mode value or the Sec-FedCM-CSRF thing. The value of the former is that it will compress better and it reuses an existing mechanism.

Activity

  1. npm1 commented on Aug 4, 2022

    @npm1
    Collaborator

    Is the proposal to add a new mode for Sec-Fetch-Mode, which would be added to all browser requests within the FedCM API? That seems reasonable to me.

  2. cbiesinger commented on Aug 4, 2022

    @cbiesinger
    Collaborator

    Hmm yeah looking at https://fetch.spec.whatwg.org/#concept-request-mode it seems like adding a fedcm method might be best. @annevk do you have any thoughts on that?

  3. domenic commented on Aug 11, 2022

    @domenic
    Contributor

    I'm not sure about this. The fetch mode concept is currently used to figure out major modes of the processing model for fetch, in terms of what results in network errors, what kind of security properties are required, how credentials are processed, whether early hints are respected, whether responses are opaque, etc.

    I can't find anywhere in the spec that actually invokes fetch in a rigorous way, e.g. says what request input is used to the fetch algorithm (this seems very bad!!). But I am hoping that the fetch that this spec does is just a normal "cors"-mode fetch. So inventing a new mode doesn't seem right, in that case.

  4. npm1 commented on Aug 12, 2022

    @npm1
    Collaborator

    Hmm thanks for the context. @martinthomson based on the above I suspect we should keep the new header? WDYT?

  5. bvandersloot-mozilla commented on Aug 14, 2022

    @bvandersloot-mozilla
    Collaborator

    I can't find anywhere in the spec that actually invokes fetch in a rigorous way,

    This was one of Anne's complaints as well. I think that it started to get defined in sections like check the root manifest, but isn't quite finished.

    This spec doesn't actually do a normal "cors"-mode fetch- it has two types of request that are more specific. One is credential-less and referrer-less and another is credentialed.

    One way forward that makes sense to me is making two new Sec-Fetch-Mode values, "fedcm-credentialless" and "fedcm-credentialed", which each specify the correct behavior within the constraints of Fetch. This also removes the need for the Sec-FedCM-CSRF header.

  6. domenic commented on Aug 15, 2022

    @domenic
    Contributor

    I hope neither of those proposed fetches bypass CORS, and I hope even more ardently that neither of them rise to the level of behavioral differences that would require an entirely new fetch mode!!

    Instead, it would make most sense if they were normal, "cors"-mode fetches, which set the referrer policy and credentials mode fields of the request appropriately.

  7. bvandersloot-mozilla commented on Aug 15, 2022

    @bvandersloot-mozilla
    Collaborator

    Instead, it would make most sense if they were normal, "cors"-mode fetches, which set the referrer policy and credentials mode fields of the request appropriately.

    Okay, that would work. Then we do still need the Sec-FedCM-CSRF header.

  8. martinthomson commented on Aug 16, 2022

    @martinthomson
    ContributorAuthor

    Looking at this more closely, I don't think that the header is needed.

    A fetch with the "cors" mode ensures that the content of a resource is not readable to a random site that invokes fetch() unless the (IDP) site deliberately enables access. To ensure that only the browser reads the response, the site needs to do exactly nothing. The site can use fetch headers to perform checks, and some amount of defense-in-depth is sensible here1, but the extra check is redundant.

    For requests that mutate state (logout, token acquisition), we can insist upon a preflight by explicitly setting the use-CORS-preflight flag. But that doesn't get us what is needed. As far as I can tell, this is where things get a little sketchy because sites can set a referrer policy that prevents the inclusion of an Origin2. So a missing Origin is not a strong signal that the request comes from the UA.

    An alternative is to use the CSRF token defense used by most sites: include a value in an earlier request that proves that the request is genuine.

    In all cases, this only requires that the endpoint that the browser interacts have a URL with sufficient high entropy as to be sufficient hard to guess by a random site that invokes fetch3. I might even claim that this provides better defense than a passive signal like Sec-FedCM-CSRF because it doesn't require an additional check, though I guess that you could build an endpoint that doesn't pay any attention to a high-entropy URL component.

    Footnotes

    1. You probably want to add X-Content-Type-Options: nosniff to the response. Then check Origin and Sec-Fetch-Dest and so forth. ↩

    2. I can't see why we would allow script to make a cross-site request without Origin, so I might be missing something: the fetch spec is, as always, inscrutable. ↩

    3. The simplest way to implement something like this is to have a per-user URL, with the URL encoding the identity of the user, a nonce, and an authentication tag; see also https://www.w3.org/TR/capability-urls/. Add a key identifier or version number and you can use the same symmetric key for many users. ↩

  9. cbiesinger commented on Aug 17, 2022

    @cbiesinger
    Collaborator

    How would you provide an endpoint with a high-entropy URL, given that sites can just read it using a server-side proxying script?

    @domenic since all of these fetches are browser-mediated and also we don't expose info to the website unless the user gives permission (by selecting an account), we do bypass CORS

  10. cbiesinger commented on Aug 17, 2022

    @cbiesinger
    Collaborator

    Also, in practice, even if we did use CORS, I'm sure IDPs will have to give access to everyone anyway since there's lots of IDPs and I doubt they want to run their CORS checks against the list every time.

  11. domenic commented on Aug 17, 2022

    @domenic
    Contributor

    Bypassing CORS is VERY BAD and MUST NOT BE DONE for new features.

  12. martinthomson commented on Aug 18, 2022

    @martinthomson
    ContributorAuthor

    I don't want this to seem facetious, but we bypass CORS for DoH. That said, I agree with @domenic in this case: this can use CORS.

  13. cbiesinger commented on Aug 18, 2022

    @cbiesinger
    Collaborator

    Well, that is a very strong statement. We can probably support CORS, but why do you say that not using it is so bad in this case?

  14. cbiesinger commented on Aug 18, 2022

    @cbiesinger
    Collaborator

    Also, should we require CORS even for the uncredentialed requests?

  15. 72 remaining items

  16. bvandersloot-mozilla commented on Mar 21, 2024

    @bvandersloot-mozilla
    Collaborator

    That seems like a reasonable state for this. Sorry I couldn't be at the breakout.

  17. added a commit that references this issue on Mar 21, 2024
  18. cbiesinger commented on Apr 11, 2025

    @cbiesinger
    Collaborator

    Both the original title (the header) and the general CORS discussion have now been resolved, afaict (we use CORS for the ID assertion endpoint now). So, closing this, but feel free to comment if you disagree (although filing a new issue may be better as this one is now very long)

  19. wseltzer commented on Apr 11, 2025

    @wseltzer
    Collaborator

    Discussed at 11 April meeting notes.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions