w3c / secure-payment-confirmation

Secure Payment Confirmation (SPC)
https://w3c.github.io/secure-payment-confirmation/
Other
106 stars 48 forks source link

Proposal: WebAuthn-agnostic device binding for Secure Payment Confirmation #271

Open stephenmcgruer opened 1 month ago

stephenmcgruer commented 1 month ago

Proposal: WebAuthn-agnostic device binding for Secure Payment Confirmation

This is a high-level proposal for adding device-binding to Secure Payment Confirmation without relying on WebAuthn (at either the client or authenticator level). At time of writing it is still exploratory and should not be taken as a concrete plan until the WG has discussed and decides it is the appropriate direction to move in. The proposal is also missing detail that will need to be filled in before it could be spec'd / implemented.

Background / Motivation

Secure Payment Confirmation builds on top of WebAuthn to make it more useful for the payments industry. Today, that comes via (at least) three added features on-top of WebAuthn:

  1. Providing a consistent and clear browser-hosted transaction dialog for the user to review their transaction details and agree to the amount, payee, etc.
  2. Including transaction details in the WebAuthn cryptogram (as part of ClientDataJSON), with a goal of helping with payment requirements such as Dynamic Linking.
  3. Supporting cross-origin authentication flows, such that a merchant or PSP can initiate an SPC authentication in their domain with a relying party of (for example) the issuing bank, without having to iframe or redirect to the issuing bank.

As of late 2023/early 2024 however, we are hearing strongly from our payments partners that a significant required feature is missing - device binding. As WebAuthn passkeys can now be synced, it can be argued that they no longer meet strict 2FA requirements (being no longer a signal of device possession), and so SPC (like WebAuthn) is reduced to a single factor (biometric or possession, depending on the authentication method used).

WebAuthn/FIDO have been exploring device binding for years, and have a proposed solution in the form of DPK/SPK. However, progress in making DPK/SPK widely available/deployed appears slow. As of May 2024 no platform authenticator ships DPK/SPK, and support is not (as far as the author knows) expected across the major platform authenticators this year - not is there any commitment or expectation from any platform authenticator that they will ship DPK/SPK.

Proposal

Given the timescales and uncertainty involved with WebAuthn's SPK, develop an SPC-specific device binding solution that can be experimented with and potentially launched during 2024.

As a rough outline, during SPC authentication in the case where the passed-in WebAuthn credential is available and the user has accepted the SPC transaction dialog, the user agent would:

  1. Retrieve or create a device-specific identifier (a public-private keypair) for the unique tuple of (Relying Party ID, credential ID).
  2. Include this device-specific identifier in the ClientDataJSON. (This step proves that the browser created the device-specific identifier, defeating person-in-the-middle attacks).
  3. Upon successful completion of the WebAuthn authentication by the user, also sign over the ClientDataJSON with the device-specific identifier, and include both signatures in the output cryptogram.

The expectation is that on receiving a never-before seen device-specific identifier, a relying party might do an additional step-up (e.g., SMS OTP) to meet SCA or other regulation requirements. However in future authentications on the same device, upon seeing an already-known device-specific identifier, the relying party can simply accept the SPC cryptogram as a full 2FA.

Note that the device binding is available cross-origin (and is unpartitioned), but the user has to have gone through two layers of consent - first the SPC transaction dialog, and then the WebAuthn authentication process. See "Potential privacy concerns" below.

This device binding would be not only device specific but also browser-specific, as each browser would have its own identifier. This would mean that a user might be stepped up for an additional challenge just by switching browsers on the same device (e.g., from Chrome to Edge), but other than that the idea should still work, so this seems like an acceptable downside. This can also be seen as a feature rather than a bug, depending on ones view!

Storage of the device-specific identifier

The two obvious locations for the device-specific identifier are either in the user agent's local database (software), or in a device TPM where present. The former might not be sufficient for payment industry threat models, so we may want to restrict this proposal to device TPMs only.

SPC is currently only allowed on devices with a user-verifying platform authenticator, which might imply the existence of a TPM. However it is not clear to the author whether or not that is always guaranteed, and we have plans to expand SPC to support roaming and hybrid authenticators in the future, so we probably cannot guarantee the existence of a TPM on the current device. As such, we will need to determine what behavior we want from the SPC API if a TPM is not available.

Potential privacy concerns

Storing and returning a device-specific identifier is a potential privacy risk. The main mitigations for this risk in the author's eyes are that the user has completed a WebAuthn authentication first and that they are reasonably provably in a 'payment' context (having accepted the SPC transaction dialog). WebAuthn credentials were historically device-bound and still may be on some platforms, so in theory this proposal is no more privacy sensitive than what already exists. But a full privacy analysis should be done, and user controls/etc should be considered to mitigate or minimize privacy risk.

FAQ / Open Questions

WebAuthn-less SPC

We have heard proposals in the WG for a fully WebAuthn-less version of SPC. That proposal is very similar to this one, in that the user agent creates a key on demand which is used to sign over the details. The WebAuthn-less proposal also did not require any user verification, just that the user clicked 'Continue' on the SPC transaction dialog.

Currently this proposal does not suggest moving away from WebAuthn. Although it is something the WG can and should discuss, there are two primary concerns:

  1. Having the trusted WebAuthn credential allows us to defeat person-in-the-middle attacks, because we can sign the device-specific key with the WebAuthn credential as part of ClientDataJSON, thus proving that it was definitely the browser that provided it.
  2. Removing WebAuthn increases the privacy risk to the user for being tracked. All a user has to do is click a 'Continue' button, and a device-specific identifier is given to the site. This may still be palatable/possible, but it seems worthwhile to keep it separate from this proposal.

What happens if/when WebAuthn launches DPK/SPK?

It is awkward that this proposal essentially competes with DPK/SPK, and raises the obvious question of what happens if/when WebAuthn launches DPK/SPK (on some or all platforms). Having both the SPC-specific key and DPK/SPK could even be a higher privacy risk, as you can identify groups of (different browser, same device), however one could do that with DPK/SPK and basic browser fingerprinting anyway.

Given that DPK/SPK seems unlikely to be ubiquitous across authenticators in any obvious timescale, it seems worthwhile to just keep the SPC-specific identifier even if/when DPK/SPK comes. We could encourage folks to use DPK/SPK instead, with a goal of eventually deprecating+removing the SPC-specific identifier, but it seems like a long and unlikely path.

An alternative (credit to Ian Jacobs!) might be to design the SPC-specific device binding API surface such that the browser could silently swap to WebAuthn's DPK/SPK support when available - that is, have the result be consistent whether the backing device binding is WebAuthn or not. Investigation is needed here to determine how feasible it is, as matching WebAuthn's API shape may be infeasible.

Relation to Device Bound Session Credentials (DBSC)

Device bound session credentials do roughly the same thing as this proposal - give the ability to create a hardware-backed device identifier. The main impediments are again the time to launch (DBSC team plans to Origin Trial at earliest in late 2024), as well as increased complexity for payment partners - they would have to string calls to SPC and DBSC together and understand both technologies, rather than just calling SPC and having it 'just work'. Using DBSC might also require iframe-ing in the Relying Party, removing one of the key benefits of SPC.

Re-inventing the wheel

It is worth noting that this proposal is in some ways re-inventing the wheel of what already exists and/or will exist in WebAuthn. In particular, it means that we have to be careful to avoid all the traps/problems with signatures that WebAuthn already has solved (e.g., challenges to avoid replay attacks, choice of signing algorithms, quantum-proofing, etc). Where possible, we should look to write the spec relying on WebAuthn concepts, even if the actual key creation and storage does not use WebAuthn authenticators.

Device attestation

Along with device binding, we have also heard interest from the industry for attestation - that is, some way of proving that the storage/provider for the keys involved is a given known entity. The question of attestation is controversial, with both privacy as well as ecosystem impacts (e.g., it risks posing a barrier to entry for new browsers and/or platforms, if major players won't accept their keys as valid). At this time, this proposal deliberately does not include attestation of the browser or the underlying key storage system. The author wishes to explore if this device binding signal alone will suffice, without diving into the difficult world of attestation. At time of writing, the number of implementations of SPC is also small, and therefore attestation is of limited value.

Next Steps

As of time of writing, the next step is for the WG to discuss the proposal and determine if (a) it will suffice to meet the needs of the industry, and (b) if its adoption would accelerate/unlock usage of SPC among potential adopters. If the answer to both is reasonably close to 'yes', then there is non-trivial follow-on work needed to spec and build a prototype implementation of this for experimentation. The Chrome team is interested in tackling that this year, potentially (no promises!) in a Q3 timeframe for prototyping.

ianbjacobs commented 1 month ago

Thank you, @stephenmcgruer!

Regarding DBSC, I think these should be described as complementary technologies: DBSC for 0-factor authentication, and SPC for 1- or 2-factor. DBSC keys are origin- (and browser-) bound because they are silently available. SPC keys are cross-origin due to the user consent. DBSC is best used before a step-up of a user on a recognized origin / device pair. SPC is best used when step-up is needed.

RByers commented 1 month ago

This proposal looks awesome to me, thanks @stephenmcgruer!

+1 to @ianbjacobs's point on DBSC. I think user mediation is a key variable in all these different technologies (when user-mediated you can do cross-origin, without it you can't). You mention iframing, but that would only work in cases where you have third-party storage (SAA etc.), not at scale, right?

In terms of what happens if SPK/DPK launches, personally I think having a choice of technology would be a good thing. I don't think we should silently change the threat model properties of SPC. Once a developer has opted into a browser-bound (and so device-bound) key, I think that's a contract we've made that shouldn't later get relaxed to be only device-bound. There are some threats involving malicious browser apps where this distinction could be important.

In terms of re-investing the wheel, does WebAuthn REALLY already solve the device binding problem? Only for roaming authenticators, right? I'd argue the underlying problem remains unsolved on the web (despite years of debate) and so we shouldn't feel at all bad about solving it ourselves here, specifically for payments. From my reading of the debates, the constraints for solving it in a payments-specific way are substantially less than the constraints for a generic solution for device-bound credentials.

+1 to leaving device attestation out of scope for now. That's a hornet's nest of complex and highly-charged tradeoffs that I have no desire to try to navigate again.

From a privacy perspective, I think we could make a further improvement above WebAuthn here by binding the storage of the key to browser site storage. That is when a user clears cookies for a site, it would also clear (or otherwise reset or render inoperable) any of these keys tied to that origin. If we do that, then it seems like strictly a privacy improvement over WebAuthn and strictly less of a privacy risk than other more generic forms of user-mediated cross-origin storage (Storage Access API, FedCM, etc.).

ianbjacobs commented 1 month ago

@stephenmcgruer, moving some ideas and questions from today's call to this thread:

RByers commented 1 month ago

Question: yes, the key should be clearable by the user. But if cleared periodically by the browser automatically, could it be more long-lived than 3p cookies since there is extra user consent involved?

FWIW my expectation here (as a Chrome lead) was absolutely we would have this persist indefinitely by default. Are there scenarios where we'd need to support a non-indefinite expiry time? I'd personally prefer to set the expectation (in contrast to cookies) that these live until the user manually deletes them.

ianbjacobs commented 1 month ago

@RByers, thanks for that answer!

stephenmcgruer commented 1 month ago

Apologies for the delay in replying here. I'm going to jot down answers to the comments/questions posed by Ian, and then later incorporate them into the initial proposal post:

There was a suggestion to make the device key available upon registration so that the RP can avoid a step-up when the same browser is used at authentication time.

I'm in two minds about this. We certainly could do this, if the WebAuthn credential is created with the thirdPartyPayment extension set. However, currently registration is very deliberately fairly agnostic to SPC and is really a 'pure' WebAuthn thing (even when using the thirdPartyPayment extension) - but making this change would introduce something very SPC-specific there. It also makes the experience more inconsistent - the device-bound key is sometimes available immediately for a credential, and sometimes not.

I could be persuaded ;).

Question: will key be bound to the profile?

In practice in Chrome, yes. Specification wise, I suspect we would only spec a requirement that the key be device bound and not synced between devices (as far as the user agent can enforce this - technically the underlying platform could do all sorts of things to sync the device bound key if it really wanted to, though in practice I'm confident that won't occur.

Question: what domain(s) would the key be bound to?

As per the proposal above, I expect that they key would be bound to the tuple of: (Relying Party ID, credential ID) (and a given browser/device). So that's the relying party domain, and a specific WebAuthn credential for it.

Question: could we open up a direct line of communication to the issuer to send the assertion?

Definitely possible! We've historically not touched this for SPC based on partner requests to not require direct/live involvement from the relying party, but we could change that. The usual approach for this is to specify a ./well-known URL path, and then the browser can call it during the flow (after user consent/verification, since this would be sharing data across domains).

Question: what change to 3DS would be necessary to support this (even if this is not tied exclusively to 3DS)?

Would be happy for one of our 3DS friends to answer this, otherwise I will need to go look at the 3DS spec :). For the original proposal, there will have to be fields in the second A-Req to carry back the device bound key as well as the cryptogram from it, but maybe we can find a way to fit it into the existing cryptogram.

For the 'direct line of communication', I don't think any 3DS change would be required - the browser would use the Relying Party's domain to open communication, and it would be a side-channel outside of 3DS.

Question: Could the key be reused outside of SPC?

In the above proposal, no, but if that's of significant value then we can explore it. Would be good to understand the use-cases more so we know what direction to shape it.

Question: yes, the key should be clearable by the user. But if cleared periodically by the browser automatically, could it be more long-lived than 3p cookies since there is extra user consent involved?

(Rick answered above)

Question: Would this work in a custom tab? (the answer was "yes").

If Chrome is the browser backing your custom tab, the answer is yes.

RByers commented 4 weeks ago

In practice in Chrome, yes. Specification wise, I suspect we would only spec a requirement that the key be device bound and not synced between devices (as far as the user agent can enforce this - technically the underlying platform could do all sorts of things to sync the device bound key if it really wanted to, though in practice I'm confident that won't occur.

FWIW I think we should have the specification be unequivocal about this: a conforming implementation must be device-bound (when requested). It then becomes our (user agent's) problem to do our best to implement this reliably, or fail the request if we cannot.