w3c / webauthn

Web Authentication: An API for accessing Public Key Credentials
https://w3c.github.io/webauthn/
Other
1.15k stars 165 forks source link

Cross origin authentication without iframes (accommodating SPC in WebAuthn) #1667

Open akshayku opened 2 years ago

akshayku commented 2 years ago

On WebAuthn WG call on 2021-08-25, a proposal concerning secure payment confirmation (SPC) was discussed which probably originated from web payments groups. Attaching for more details: [WebAuthn WG August 2021] Secure Payment Confirmation.pdf

In above proposal, a mini proposal is to open up authentication to cross origin without iframes. Opening up this issue to hopefully have the concentrated conversation around cross origin authentication without iframes and want to talk about security, privacy and user experience and potential misuse.

So at the moment, we don't allow authentication outside of origin in webauthn. We allowed it in iframes in L2, but don't allow it for any other website to be able to invoke .get() call credentials without iframes.

Recently, we discussed to open up .create() call inside iframes. Till this point RP is in control. If it chooses to, like all of non-payment scenarios, it can choose to not enable these calls in iframes. And if they do, they know who the parent is so that they can potentially filter out origins that they trust.

I see three kind of RPs with different levels of control.

  1. RP who never wants to do .create() or .get() calls outside of their origin. Current webauthn spec protections allow that which really helps in phishing resistant property of WebAuthn.
    • Most RPs live in this space
  2. RP who is OK with iframes but only want to do in iframes because they are still in control of who can invoke webauthn ceremonies.
  3. RP who wants .create() and .get() calls outside of origin. Like merchants, who wants to do on-behalf of banks.
    • The above Web Payments proposal is not proposing .create() call outside of iframes at the moment. But I heard @christiaanbrand saying that he wants to do that in future.

The most concern I have is around the third category of RPs/Scenarios which will negatively impact Category 1 and also category 2.

IIUC, the proposal is to only allow credentials who are marked as SCP compliant to be opened up for now for authentication in cross origin case.

If we cannot determine this without tampering, then we have privacy issues. A phishing website will get the credentialID and invoke it in their origin, user will be prompted with the dialog, which most likely they don't much read, and user approves and website knows that user has credential for a website which they have no right to enquire.

In above context, let's get one thing out of the way. CredentialIDs are public and that's why we don't store PII information in that. In webauthn designs, we allow with username flows, where given a username, credentialIDs being returned for passwordless authentication silently. Ofcourse, RP can add fake one, but they need to also provide the real ones. Even outside webauthn, credentialIDs are kind of treated as semi public info. And till now this was not an issue because no other origin can really use them. So credentialIDs will be known to many parties.

Another point I heard was around it is only applicable for non-discoverable credentials. I don't understand why. I can understand that this design only works if used in allowlist context, which can be satisfied by both non-discoverable as well discoverable credentials. And restricing it to only with allowlist, I am not sure what we are getting. As mentioned above, credential IDs are not really protected in any full secure way by the RPs.

Third argument I heard that any websites ability to popup authentication, even if we restrict it SCP credentials only is only a nuisance. I argue that it is a privacy issue and a possibly a phishing vector. It gives ability for a random RP to almost know for certainty that a credential exist for a website. And that is why, the second category above which says, I have cases around cross-origin authentication, but I only want it to be inside an iframe. And that should be RP's choice. Even if this is nuisance, it seriously hampers the webauthn brand.

Till now, I am only thinking from RP's persctive. I haven't thought through, where the user choice in all of this.

Overall, it seems that this is dangerous and in pursuit of solving one desire to not have iframes (which I don't disagree with per say, but just recently we rejected other legitimate use cases around raw signatures), we are messing up with core fundamentals too much here. Ofcourse, I don't have the full design and I may be wrong here.

@agl @christiaanbrand @equalsJeffH @ve7jtb for above questions and clarifications if I misunderstood things.

ve7jtb commented 2 years ago

Unless we find some other field in a discoverable credential to store the canBeUsedFor3PSPC flag, I see there basically being two options.

  1. all 3P credentials are created in a different RPID namespace.
  1. Use only 1P credentials at the CTAP layer. If a RP wants to flag a credential as 3P for SPC then that flag would be local to the particular browser instance the credential was created on. That is basically what we have in the current pilot. The difference is that in the 1P SPC flow any credential roaming or platform could be used now. The 3P credentials being used cross-browser and device will need to be deferred to CTAP2.2 for a solution. That will probably add one to two years to the timeframe for a broad deployment of the 3P credentials in a cross-browser way.

Neither solution seems to be all that the banks are asking for. However we are trying to adapt an existing platform to the new requirements. It is not surprising that some compromise is required.

I guess the advantage of the second option is that it is OK for the 1P use case that seems to be the highest priority and will work with some limitations for 3P SPC in the short term and will work fully after updates.

The namespace option is a bit of an ugly hack that has no easy fix going forward so will haunt us for a long time. The one advantage is that it would work with existing authenticators at the cost of RP flexibility.

If CTAP2.2 prioritized this and the new purpose flag field is small enough to put in the credentialID we could see prototypes in 2022. I don't know how long it would take the platform authenticators to change. We tend to assume they are just software so could change quickly. I have yet to actually see that happen with any of them:) So option 2 would take time before it would work cross-browser. Depending on the number of browsers planning on supporting SPC this might be an acceptable compromise.

emlun commented 2 years ago

One thing we discussed a bit on the 2021-12-15 call: there's some risk of introducing a (weak) de-anonymization attack vector here. Say a malicious website wants to confirm a guess at someone's identity, and knows some of their SPC credential IDs. The malicious website could nag the victim with an SPC prompt to authorize a payment of $0 or something, until the victim agrees just to get rid of it. The malicious website has now successfully identified the victim, and the important point here is that the victim never registered to the malicious site. This kind of attack is currently possible only on the domain where the credential was created, but cross-origin credentials could be vulnerable to this on any domain.

It's a weak attack since the attacker needs to already know the victim's credential IDs, but this does mean that SPC/cross-origin credentials would have (slightly) weaker privacy guarantees than "first-party"/"same-origin" credentials (all current WebAuthn credentials). Especially since SPC as currently proposed shares credential IDs across domains, significantly increasing their exposure.

The main mitigation I can see is if RPs have to actively opt in to cross-origin credentials, and ideally not by a single binary setting but by an allow-list of domains (either a static list or a dynamic query like how Access-Control-Allow-Origin works in CORS). That wouldn't prevent the attack, strictly speaking, but it would limit the attack surface to some set of "trusted" origins defined by the credential issuer. Although that set might in practice end up being "allow any domain" in many cases anyway...

stephenmcgruer commented 2 years ago

Acknowledging that this issue has been long and contains many sub-discussions and proposals, I wanted to be clear on what we (WPWG) think are the next steps here.

At this point, we believe that we need authenticator-level support for the following two things:

  1. At creation time, the ability to ask the authenticator to set a bit in the credential, indicating that the credential may be used cross-origin for SPC.
  2. At authentication time, mechanism(s) to ask an authenticator (or to determine directly from a credential ID), without user interaction with the device:
    1. If a credential is SPC-enabled.
    2. If a credential is available on the authenticator. (We believe that this similar to that which is required for the WebAuthn Conditional UI Proposal.)

(Note that the above presumes that SPC in a 1p context will always be available, and that the bit will indicate that it is also allowed from a 3p context. As always, login will never be allowed from a 3p context.)

As we understand it, these require CTAP level changes, so our next step is to send a proposal to the FIDO2TWG for these, within the next 2 weeks. Please feel free to give us any input before we move to do that :).

ve7jtb commented 2 years ago

Based on a credentialID the platform can determine if that credentilID exists on the authenticator assuming that it is not created at credprotect level 3. In principal the flag could be reported in an extension as part of the normal get assertion with UV=0 UP=0. We could also do something with credential management, however that currently requires authentication.

It gets more complicated if there is a requirement for this to work without an allow list.
Without the credential ID you would need an authentication if the credentials are created at credprotect level 2 (The default in Chrome)

One option would be to always create cross-origin capable credentials at credprotect level 1. That would allow them to be discovered without forcing a user verification first.

That was the original design but the Google privacy team wanted to enforce some sort of authentication before relating the information as I bleve they consider the RPID storage to be sensitive. @AGL will have better info on those concerns that might resurface if we start making discoverable credentials at L1.

Not a problem if there is always an allow list.

John B.

stephenmcgruer commented 2 years ago

Not a problem if there is always an allow list.

The SPC spec currently requires an allowList (we called it credentialIds), so the short term seems ok.

Thinking long term - my gut feel is that 'we' (everyone) wouldn't want discoverable credentials to work cross-origin as it feels even more dicey security/privacy wise; but I may be wrong.