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

Enforce CORS on the Identity Assertions endpoint #428

Closed
antosart opened this issue Feb 9, 2023 · 59 comments · Fixed by #547
Closed

Enforce CORS on the Identity Assertions endpoint #428

antosart opened this issue Feb 9, 2023 · 59 comments · Fixed by #547

Comments

@antosart
Copy link

antosart commented Feb 9, 2023

The spec says in a red note that

An IDP MUST check the referrerOrigin header to ensure that a malicious RP does not receive an ID token corresponding to another RP. In other words, the IDP MUST check that the referrerOrigin header is represented by the client_id. As the client_id are IDP-specific, the user agent cannot perform this check.

This seems a crucial check that the IdP must implement, as it would otherwise allow anyone the get the user's id token. Wouldn't it be safer to enforce CORS here (i.e.: the user agent throws an exception if the response does not include the correct Access-Control-Allow-Origin header)? CORS exist exactly for this usecase. And this would make it impossible for IdPs to forget to implement this check.

@antosart
Copy link
Author

antosart commented Feb 9, 2023

(I know there was a longer discussion regarding CORS in #320, but it seems to me that there we were mostly concerned with the requests which did not want to disclose the RP to the IdP, and that we did not take this into consideration.)

@npm1
Copy link
Collaborator

npm1 commented Feb 9, 2023

I don't think that CORS would avoid the problem being noted in the red note. The problem is that the IDP could in theory just use the clientID to determine what the client is, and this clientID is provided via JavaScript, so the website could lie about it. So it is inevitable that they have to verify that the clientID being used matches what the user agent says is the RP.

@antosart
Copy link
Author

Yes. In my opinion, responding with the appropriate CORS headers means exactly that the server explicitly acknowledges that it performed the appropriate checks (which of course are specific to the business logic of the API, and in the case of FedCM boil down to checking that client_id and origin match).

@domfarolino
Copy link

So the threat scenario here is where evil.com invokes FedCM with some trusted RP's public client_id in hopes of impersonating the RP and stealing the user's credentials token, right?

The absolute minimal CORS check that an IDP might perform would return ACAO headers to any trusted RP, independent of client_id, which would then allow trusted RPs to impersonate each other, but that still seems like a base-line improvement as it protects against evil.com impersonating a trusted RP (when talking to the IDP). And a more complete CORS check would indeed consider client_id and ensure that ACAO headers only get returned when the Origin and client_id match, as @antosart mentions.

Separately, it seems odd that if client_id is so crucial to the equation, we don't do any browser-side verification at all, instead hope the server does some based on the Origin, for which the usual verification mechanism is CORS. The note mentions that the browser can't do the verification because the client_id is IDP-specific, but the browser knows which IDP it is talking to, so maybe it could do some work here? Anyways, it might be too late in the game to suggest that.

@npm1
Copy link
Collaborator

npm1 commented Feb 10, 2023

I suppose it is true that the browser could add a step to enforce that the RP is not lying about the client ID. For instance, the user agent could send client_id and the Origin to the IDP and the IDP needs to reply with some confirmation that those are indeed a match. It should be coupled with some fetch, for instance the ID assertion fetch, to not introduce latency. However, I do not think CORS is the right header for this because it increases the chance that the IDP accidentally makes the id assertion endpoint readable via other JS APIs from all RPs, which would be much worse than the attack being described here.

@cbiesinger
Copy link
Collaborator

@antosart ping -- did you have thoughts on npm1's comment above?

I guess we could add an origin field in the ID assertion response if people find that valuable

@achimschloss
Copy link
Contributor

However, I do not think CORS is the right header for this because it increases the chance that the IDP accidentally makes the id assertion endpoint readable via other JS APIs from all RPs, which would be much worse than the attack being described here.

Using CORS to check if the pair of client_id and origin in a client side fetch call is valid is common practice for credentialed js calls with IDPs. The IDP would return all elligible origins for a specific client ID using CORS (the above mentioned easy method would not be possible honestly at least here in the EU)

Access-Control-Allow-Origin: <ORIGIN> Access-Control-Allow-Credentials: true

I guess we could add an origin field in the ID assertion response if people find that valuable

Assuming we are shifting and removing referer and use origin instead this is a must. In the end the IDP must have the client_id and the origin available (which is the key part here) and will check if the pair is as expected.

@achimschloss
Copy link
Contributor

achimschloss commented Mar 2, 2023

IDP accidentally makes the id assertion endpoint readable via other JS APIs from all RPs, which would be much worse than the attack being described here.

That might be a fair point as the FedCM API Call is not a classical client side fetch from the RP itself

@achimschloss
Copy link
Contributor

I guess we could add an origin field in the ID assertion response if people find that valuable

Assuming we are shifting and removing referer and use origin instead this is a must. In the end the IDP must have the client_id and the origin available (which is the key part here) and will check if the pair is as expected.

Sorry I misread that - you mean the IDP should return the origin in its response? How does that ad value?

@antosart
Copy link
Author

antosart commented Mar 2, 2023

IDP accidentally makes the id assertion endpoint readable via other JS APIs from all RPs, which would be much worse than the attack being described here.

It's not totally clear to me where the risk would be in that case. In order to receive an ID token, the RP would still have to send an authenticated request with the proper cookie. Basically this would just mean that the RP could perform the auth flow without using the FedCM API (again, assuming it can send the first-party IDP cookie). If the IDP want to open this API only to FedCM, it can still check the X- header.

@domfarolino
Copy link

Also I want to make sure I fully understand the risk of using CORS here. IIUC, there is no risk of exposing the tokens to JS on any old site, right? (Because ACAO: * cannot be used with credentialed CORS requests). So the threat is that the IDP risks exposing tokens to the JS of trusted RPs? If the RPs are trusted, is that so bad? Maybe that's a dumb question — sorry for my lack of FedCM knowledge.

@cbiesinger
Copy link
Collaborator

The concern is that they will echo back the origin in ACAO, and forget to check the sec-fetch-dest. this would mean that websites can bypass FedCM and the corresponding user confirmation and send a request to the token endpoint directly.

@domfarolino
Copy link

If they naively echo back ACAO with any old origin, then the IDP isn't checking that the origin is a trusted RP, which the spec currently states is a requirement for security (see OP), so that threat (from enabling CORS) doesn't leave us any worse off than the current state of affairs.

@cbiesinger
Copy link
Collaborator

Fair enough, but my point is still that even if they do check that it's still possible to forget to check sec-fetch-dest, and suddenly the result becomes readable. I'm skeptical that using CORS adds any real security.

@domfarolino
Copy link

It solves the problem in the OP, right? I'm not saying it has no drawbacks (script readability), but I think it does solve that specific problem. So let me just see if I'm accurately understanding the options here:

Not using CORS:

  • Servers that fail to implement the Origin == client_id check are vulnerable to the attack in the OP, where evil sites spoof trusted RPs:

    This seems a crucial check that the IdP must implement, as it would otherwise allow anyone the get the user's id token. Wouldn't it be safer to enforce CORS here (i.e.: the user agent throws an exception if the response does not include the correct Access-Control-Allow-Origin header)? CORS exist exactly for this usecase. And this would make it impossible for IdPs to forget to implement this check.

  • But we ensure that the token is never readable to cross-origin script ever

Using CORS

  • Mitigates the issue raised in the OP; it's impossible for an evil site to spoof a trusted RP
  • Servers that fail to check Sec-Fetch-Dest are vulnerable to returned tokens being readable by script, specifically on trusted RPs — for tokens to be readable by script on random evil non-RP sites, the server would already be failing to do what the current spec states is required for security

Is this an accurate summary?

@cbiesinger
Copy link
Collaborator

I'm not convinced that either of these is true:

  • there's a risk that IDPs will not check that Origin and ClientID are valid and match each other
    • Our main IDP partner was very conscious of this need
  • Requiring them to send ACAO makes it more likely that they will do that check

Why are you assuming especially the latter?

@domfarolino
Copy link

I'm not. If I were, I guess I'd base that hunch off of the fact that it is a very standard and well-known security check to implement so it would be harder to miss than the FedCM-specific check that is required.

But the argument for CORS (which I'm not necessarily making, I'm just trying to map the tradeoffs here) doesn't rely on them being more likely to do the CORS check. The argument is that if they don't do either of the checks, the former fails open while the latter fails closed.

@cbiesinger
Copy link
Collaborator

Well not quite... the former ensures that they echo the incoming origin onto ACAO and fails closed otherwise. It does nothing to ensure they do any checks in addition to that echoing.

@domfarolino
Copy link

If they send back an ACAO header in any way, it implies they're doing the checks. If they do them wrong, that's on them, but at least it requires them doing some logic to implement the standard security check, and fails if that logic is entirely absent. Whereas if the "check" logic is entirely absent today it just fails open. Idk that seems like a win to me, but we might just disagree about that.

I can't help but think that CORS is perfect to mitigate the scenario that @antosart raised in the OP.

@npm1
Copy link
Collaborator

npm1 commented Mar 15, 2023

(Back from vacation) I think your summary is accurate, @domfarolino. Although a more comprehensive summary could have the third option, which is adding an ad-hoc check to ensure that the client_id and Origin match. There's also a downside to CORS that it has semantics which do not seem to apply in this case. In the CORS scenario, even though CORS needs to be used, the IDP is by no means saying 'feel free to share this info outside of FedCM with the RP'. This is unintuitive IMO.

@antosart
Copy link
Author

@npm1 I am not sure I understand what you mean by 'feel free to share this info outside of FedCM'

If the IdP wants to provide an API only for FedCM, then I believe they should block all requests with non-matching Sec-Fetch-Dest header.

@npm1
Copy link
Collaborator

npm1 commented Mar 15, 2023

What I mean is that having the CORS requirement could give the impression to developers that they can also obtain the credentials via other fetches which require CORS, like a JS fetch(). This would not be the case, as you mention, since the IDP would protect the resources via Sec-Fetch-Dest checks. Are there other examples in the web platform where CORS is required but the fetches should not be allowed under regular mechanisms protected by CORS?

@antosart
Copy link
Author

I think that is a good point, I don't think there are any other such mechanisms.

On the other hand, I am unsure about the sentence "fetches should not be allowed under regular mechanisms protected by CORS". Is this really a requirement? An IdP which would like to support vendors which do not implement FedCM might want those APIs to be reached via fetch, no?

@cbiesinger
Copy link
Collaborator

I'm not aware of a vendor which uses cross-origin fetches for that purpose (vs an <iframe> and same-origin fetch + postMessage).

@samuelgoto
Copy link
Collaborator

samuelgoto commented Mar 15, 2023

There's also a downside to CORS that it has semantics which do not seem to apply in this case.

At the risk of not adding much information to this thread, I just wanted to +1 what @npm1 said that I think CORS has a semantics mismatch problem here: it is intended for "Cross Origin Resource Sharing" (right?), which isn't the intention here: this (the identity assertion endpoint) is an endpoint that is designed to be called by the browser for the browser. We specifically do not want to expose this endpoint across origins, e.g. unintentionally through fetch(). So, I think I could be convinced that the mechanisms that we placed with CORS would help (although I can't say that I am convinced), but I think there is a perception/semantic/branding challenge here with CORS in that it is intended to be used in a scenario that we explicitly want to avoid (cross-origin resource sharing) and the risk that we could take that this endpoint gets exposed in the future because of the semantic mismatch (e.g. maybe we'll introduce fetch2() which will make the endpoint available in the future).

@antosart
Copy link
Author

I don't think there is a qualitative difference from other endpoints, and I don't think that we can give a precise meaning to "is designed to be called by the browser for the browser".

As an example - but I am sure there are others - cross origin web fonts declared in a @font-face also require CORS in order to be loaded. In some sense, they are also fetched by the browser for the browser (for rendering the page), and the page probably does not really need access to the raw font data (hence probably there is no use-case for the page to fetch() a web-font), yet the font data is needed for the page (for rendering it). If a server wants to serve web-fonts cross-origin, but it does not want them to be accessible via fetch (for whatever reason), then it should check the Sec-Fetch-Dest header.

So, I don't really think that CORS is 1-1 related to fetch. I think CORS means: this resource can be shared with / used for a page with this origin. And I believe this is exactly what happens for FedCM.

@npm1
Copy link
Collaborator

npm1 commented Mar 16, 2023

That's a fair example. I guess CORS is already somewhat overloaded in the sense that it is used to allow access via various web platform APIs. From that perspective, using it here may not be totally wrong. I still think having a specific check of client id vs origin in the FedCM fetches is a bit better, but I can see how security folks might not want to introduce another mechanism to perform the check when CORS can be argued to be workable here. Is that the reason you prefer CORS to a FedCM specific check?

@domfarolino
Copy link

Is that the reason you prefer CORS to a FedCM specific check?

Not exactly sure who this is directed to, but that's kind of where I'm coming from, yes. It's the common security protocol that we all think about when adding new features etc, and I think having less unique ones makes it all the less likely that we'll miss something when making future changes. Curious to hear what @antosart thinks though.

@antosart
Copy link
Author

Not exactly sure who this is directed to, but that's kind of where I'm coming from, yes. It's the common security protocol that we all think about when adding new features etc, and I think having less unique ones makes it all the less likely that we'll miss something when making future changes.

@domfarolino yes that's exactly my point. I believe that relying on well-established, well-understood security primitives makes it easier to reason about security properties, both for spec/features developers and for web developers.

@npm1
Copy link
Collaborator

npm1 commented Mar 30, 2023

To answer the CSP question, we do a 'manual' check in step 3 here https://fedidcg.github.io/FedCM/#fetch-the-config-file (this for for the well-known file, the first fetch performed in FedCM), since there is no client passed onto fetch that would allow getting this for free.

@judielaine
Copy link

judielaine commented Apr 3, 2023

I don't think that CORS would avoid the problem being noted in the red note. The problem is that the IDP could in theory just use the clientID to determine what the client is, and this clientID is provided via JavaScript, so the website could lie about it. So it is inevitable that they have to verify that the clientID being used matches what the user agent says is the RP.

In OAuth2 Client Credential Grant the token returned by the IdP to the SP is used to call a back channel endpoint. That endpoint has client identity authorization. There can be many different clients at an origin, so the client's own credentials can be used. I don't know if PKCE has the client authentication included on the backchannel flow.

@cbiesinger
Copy link
Collaborator

cbiesinger commented Apr 11, 2023

One issue with enforcing CORS on the identity endpoint is that the fetch spec (and thus, Chrome's networking stack) does not really allow for what we want. With CORS, what we want is:

  • An Origin header (and CORS check based on that) that has the RP's origin
  • Send first-party cookies (i.e. including SameSite: Lax and Strict) to the IDP, because this is initiated by the browser and not really third-party. This is important because we don't want to require IDPs to switch their auth cookies to third-party

And as far as I can tell, this is not possible today with fetch.

@antosart
Copy link
Author

@cbiesinger I think you are right, but fetch also does not support doing a non-CORS request sending all cookies with a third-party Origin header, no?

@cbiesinger
Copy link
Collaborator

@antosart my thinking was to have the caller (the fedcm spec) append an ('Origin', rp's origin) entry to the header list before calling fetch, however I see now that https://fetch.spec.whatwg.org/#append-a-request-origin-header would append an additional Origin entry to the header list (as this is a POST request). I wonder what result that would produce; I guess it should technically end up sending two Origin headers.

I am realizing this works in Chrome because since we do not set a request initiator, the networking stack does not set an origin header itself, so the origin header we set in the fedcm code remains.

In short, you are correct :(

@cbiesinger
Copy link
Collaborator

That said @antosart -- for the no-cors case we have a plan in form of whatwg/fetch#1533; we have no plan for how to spec the CORS suggestion

@bvandersloot-mozilla
Copy link
Collaborator

Let me step into this now that I'm back from a leave.

This seems like a case where CORS should be a requirement to me. The ID token is being handed directly to the FedCM caller. IIRC, we talked about this particular request in the meeting where we developed "unsafe-no-cors" as an idea. I thought we settled on exactly the points @domfarolino hits here:

That, along with the facts that the FedCM request (which basically gets around 3p cookie blocking) makes the request essentially as a 3rd party request (since the request's origin is the RP's origin), with 1p cookies, and for partial consumption by the initiating page (IIUC), all to be great reasons to use CORS. Am I missing something about the risks?

To answer that last question: not that I can see.

I also assumed that these cookies would have to be set to SameSite=None in order to function

but that work (whatwg/fetch#1533) has not been completed.

That was going to be worked on (wrapped up?) by the Chrome FedCM team during my leave- is there anything that has happened out of band there?

@cbiesinger

Send first-party headers (i.e. including SameSite: Lax and Strict) to the IDP, because this is initiated by the browser and not really third-party. This is important because we don't want to require IDPs to switch their auth cookies to third-party

It's been a while but I think I assumed that IDPs would have to set their auth cookies as third-party to work in federated contexts in the first place. I take that this is not the case. Is whatwg/fetch#1637 your proposed solution to the conflict you pointed out here: #428 (comment) ?

I need to refresh myself with how the Firefox implementation functions right now- The lack of resolving the CORS issues in the spec means we were flying a bit in the dark and it seems to be biting the spec back here.

@npm1
Copy link
Collaborator

npm1 commented May 15, 2023

This seems like a case where CORS should be a requirement to me. The ID token is being handed directly to the FedCM caller. IIRC, we talked about this particular request in the meeting where we developed "unsafe-no-cors" as an idea. I thought we settled on exactly the points @domfarolino hits here:

The current consensus is to use "unsafe-no-cors" (or whatever name) for the endpoints, and to also use CORS for the id assertion endpoint. The ID assertion endpoint still needs the forbidden header protection.

I also assumed that these cookies would have to be set to SameSite=None in order to function

Hmm looks like you are right. I think our team got confused and at some point we thought that these cookies would be SameSite=Lax, but those are not sent in crosss-site iframe requests. So I don't see how the cookies could be Strict or Lax.

That was going to be worked on (wrapped up?) by the Chrome FedCM team during my leave- is there anything that has happened out of band there?

Apologies, that's on me. We got distracted by other work plus the request to use CORS on the ID assertion endpoint, and we did get a resolution on that one. Now that you are back, it may make more sense for you to keep pushing the PR, but I can also help if you want, let me know and we can sync to distribute the work.

@cbiesinger
Copy link
Collaborator

I also assumed that these cookies would have to be set to SameSite=None in order to function

but that work (whatwg/fetch#1533) has not been completed.

That was going to be worked on (wrapped up?) by the Chrome FedCM team during my leave- is there anything that has happened out of band there?

@cbiesinger

I am sorry that I have not made progress on that :(

Send first-party headers (i.e. including SameSite: Lax and Strict) to the IDP, because this is initiated by the browser and not really third-party. This is important because we don't want to require IDPs to switch their auth cookies to third-party

It's been a while but I think I assumed that IDPs would have to set their auth cookies as third-party to work in federated contexts in the first place. I take that this is not the case. Is whatwg/fetch#1637 your proposed solution to the conflict you pointed out here: #428 (comment) ?

The last paragraph of https://fedidcg.github.io/FedCM/#browser-api talks about this pretty explicitly. (noticed this while reviewing https://github.com/fedidcg/FedCM/pull/473/files#diff-40cc3a1ba233cc3ca7b6d5873260da9676f6ae20bb897b62f7871c80d0bda4e9R305)

@cbiesinger
Copy link
Collaborator

@antosart my thinking was to have the caller (the fedcm spec) append an ('Origin', rp's origin) entry to the header list before calling fetch, however I see now that https://fetch.spec.whatwg.org/#append-a-request-origin-header would append an additional Origin entry to the header list (as this is a POST request). I wonder what result that would produce; I guess it should technically end up sending two Origin headers.

I am realizing this works in Chrome because since we do not set a request initiator, the networking stack does not set an origin header itself, so the origin header we set in the fedcm code remains.

In short, you are correct :(

I think this may actually not be an issue, because https://fetch.spec.whatwg.org/#append-a-request-origin-header would just append the request's serialized origin, which would be correct in this situation (we set the origin correctly in https://fedidcg.github.io/FedCM/#fetch-identity-assertion)

One thing I did notice talking with Ben and Nicolas now is that we need to access the internal response because the regular one is filtered due to https://fetch.spec.whatwg.org/#ref-for-concept-request-response-tainting%E2%91%A5 setting tainting mode to opaque for no-cors fetches.

@domfarolino
Copy link

One thing I did notice talking with Ben and Nicolas now is that we need to access the internal response because the regular one is filtered due to https://fetch.spec.whatwg.org/#ref-for-concept-request-response-tainting%E2%91%A5 setting tainting mode to opaque for no-cors fetches.

I don't actually think this will do the trick. At TPAC we established that ORB (Opaque-Response Blocking, in whatwg/fetch#1442, originally from https://github.com/annevk/orb) will block all cross-origin no-cors JSON responses. So per spec, even reaching into the internal response won't do anything; ORB blocks things before that stage. (It seems the Chromium implementation is not broken in this way right now because network stack perceives the request as same-origin, which is incorrect.)

@annevk
Copy link

annevk commented Sep 20, 2023

FWIW, I pointed out the ORB issue a year ago: #320 (comment).

@domfarolino
Copy link

Ah thanks! In the TPAC meeting there were a lot of blank stares and "wait, what's ORB?!"s when it got brought up, so I just naively assumed we hadn't discussed it here before.

aarongable pushed a commit to chromium/chromium that referenced this issue Sep 21, 2023
FedCM and CORS integration has been discussed in
w3c-fedid/FedCM#428, among other places, and
various flavors of the discussion revealed confusion around both the
kNoCors request mode in the implementation and spec, as well as the
`network::ResourceRequest::request_initiator`, and how it relates to the
Fetch Standard.

Some folks didn't realize that `request_initiator`, when used by the
web platform specifically, was equivalent to a Fetch request's origin
[1], so this CL helps clear this up.

[1]: https://fetch.spec.whatwg.org/#concept-request-origin

Bug: 1383340
Change-Id: If090182beb8d82e87784d6b6094f278c7f9a820d
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/4873650
Reviewed-by: Kenichi Ishibashi <bashi@chromium.org>
Commit-Queue: Dominic Farolino <dom@chromium.org>
Cr-Commit-Position: refs/heads/main@{#1199321}
@npm1
Copy link
Collaborator

npm1 commented Sep 21, 2023

Sorry for the delays, this is still something we intend to do in FedCM. After some TPAC meetings, I think we are unblocked to make the change. The ID assertion endpoint will use CORS and some fetch spec monkeypatch to pass the relevant cookies. We'll send a PSA to developers of this change and update the spec.

@yoavweiss
Copy link

A drive-by comment as I'm skimming through this. Please feel free to let me know if this was already discussed and I missed it.. (or if it's a bad idea :D)

It seems like we want want IDPs to perform 2 checks:

  • Check that the Origin matches what they expect based on the client ID - CORS would enforce them acknowledging this (even if it can't force them to run the checks correctly).
  • Check that the request's destination matches "webidentity", to verify that this is not some rogue script trying to steal the relevant credentials.

While the latter check is only required in browsers with 3P cookies, and can be solved by the IDP validating sec-fetch-destination, it may make sense to have add an extra CORS mode that would require a Access-Control-Allow-Destination headers on the response, with a specific destination that's allowed here? That would allow the client to validate that latter check, and allow IDPs to statically ensure they don't leak credentials, even if users explicitly turned on 3P cookies for some reason.

@domfarolino
Copy link

Yeah, I do like that idea. It's pretty simple and consistent with other security checks. I think there are two things working against it though:

  1. The fact that it is most useful with 3p cookies enabled, which are on their way out, so I'm not sure if there's much appetite in designing APIs around a world where they exist/are used. There certainly might be, I'm not sure.
  2. The actual security model seems a little limited to me. If you're considering SPECTRE a concern, then ACAD is very useful for requests that aren't initiated by a document, but are initiated by another "trusted" process on behalf of a document, from which that request is made with an unspoofable destination like webidentity. For these requests, the ACAD value that the server chooses actually controls which process the response enters — it allows the response to be exposed to "trusted" processes, and prevents it from being exposed to "untrusted" processes. Historically the web platform doesn't have too many of these kinds of requests I think — hence the poor support for null-client requests in those contexts, and the whole discussion of unsafe-no-cors vs not that. With that said, more proposals are definitely introducing more of these requests (FedCM, Protected Audience, Fenced Frames, Attribution Reporting) that rely on a "trusted" process making these kinds of requests on behalf of a document. Though not all of them rely on a new destination value....

@annevk do you have thoughts on this?

@annevk
Copy link

annevk commented Mar 12, 2024

My worry with Access-Control-Allow-Destination and having IDPs rely on it, is that it puts them up for timing attacks. It is much safer to reject requests early on and not waste time generating a response specific to an end user as even just the time it takes to generate the response can reveal something about the end user.

So I would be inclined to not offer this and rely on IDPs to handle the Sec-Fetch-Dest checking correctly.

(If we had origin manifests you could imagine requiring a particular destination upfront for certain paths, but origin manifests are very tricky.)

@cbiesinger
Copy link
Collaborator

Some more thoughts from today's discussion:

  • the header would be better named Access-Control-Require-Destination to match the proposed semantics
  • network stack changes would be required as well as a change to the fetch spec, because fetch needs to send network errors when the response has access-control-require-destination: webidentity but the request has sec-fetch-dest: empty (as an example)
  • if we do not make FedCM require the new header, the change is somewhat orthogonal to this issue, because IDPs can opt in whenever they want once implemented
  • if we do make FedCM require the header (that is, if we change the FedCM spec/impl to fail the FedCM request if an otherwise successful fetch request does not have this response header), this is a bit of a layering violation, but would be somewhat safer
    • this would, of course, not be backwards compatible

@yoavweiss
Copy link

It is much safer to reject requests early on and not waste time generating a response specific to an end user as even just the time it takes to generate the response can reveal something about the end user.

That's a good argument in favor of steering developers towards active server-side filtering. Having a client-side destination-based filter may be defense in depth in that case, but I admit that given the above, I'm not sure the case for that is very strong.

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

Successfully merging a pull request may close this issue.