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

Cross-origin credential creation in iframes #1656

Open
agl opened this issue Jul 27, 2021 · 47 comments
Open

Cross-origin credential creation in iframes #1656

agl opened this issue Jul 27, 2021 · 47 comments
Assignees
Milestone

Comments

@agl
Copy link
Contributor

agl commented Jul 27, 2021

In level two we supported cross-origin assertions (when allowed by the top-level) but omitted cross-origin creation because there wasn't anyone with a use-case.

We would like to revisit that and allow cross-origin creation along the same lines as assertion. We believe this will be useful in a payments context.

When making a payment there are three (or four) parties involved. The customer seeks to authorise the payment. They are on the merchant's site. A bank needs to approve the payment, and there might be a payment processor between the merchant and the bank. If the bank can make a cross-origin assertion on the merchant page then that can greatly improve their confidence that the transaction is genuine. However, that assumes that the bank has a credential for the user, and that would be aided by being able to enroll users inline. Thus the desire for cross-origin creation.

@arshadnoor
Copy link

Hi Adam (@agl ),

I concur with the use-case: that it is essential for Banks to receive digital signatures from Consumers directly when they're confirming a payment transaction at a Merchant site. But I humbly disagree with the premise that the optimal way to register Consumers is with cross-origin credential creation. I think Banks and browser companies are making a mistake and forcing the FIDO protocol/implementations to become a lot more complex than it need become - at least for this use-case.

Every Bank, IMO, is going to have to contend with FIDO sooner or later whether they like it or not. Windows 11 and Apple Passkey will ensure that. If they have to implement FIDO for their own users to interact with them directly, why would they not simply require that the Consumer register with them first and associate all their registered Public Keys for whatever payment instruments they have acquired from the Bank?

By doing so, here are all the benefits that accrue to the ecosystem:

  • Consumers only have to register with the Bank once (for each unique Authenticator they choose to register);

  • Consumers do not have to be distracted with additional friction during the Checkout process (to register an Authenticator);

  • Consumers do not have to be worried that they are being attacked by someone while shopping at a site ("What are these additional things the Merchant wants me to do?", "How do I know I can trust what I'm seeing here?", "Perhaps the Merchant has been compromised?");

  • Merchants do NOT have to create complex Checkout workflows for registration of Authenticators. When the Consumer chooses a specific payment instrument during Checkout, and the Merchant sends that information to the Bank, the Bank recognizes the instrument, finds the associated Public Key(s) and a unique challenge comes back as a response for the Consumer to sign;

  • Banks do not have to worry about whether the Consumer may register their new payment instrument with them - they can mandate it as a prerequisite to using the instrument (they already require all kinds of user actions to enable the use of a payment card before first use currently);

  • Banks can transition to digital payment instruments - instead of sending out cards - and register those instruments faster and more securely with FIDO, rather than:

    1. Wait for the Consumer to receive the card;
    2. Choose to go shopping on the internet;
    3. Choose to use a Merchant that might have implemented FIDO; and finally
    4. Choose to register at the Bank during Checkout.
  • There are too many conditional probabilities that are likely to result in very low registrations with the Bank. When registered directly with the Bank, they will have 100% compliance and the potential to offer Merchants faster Checkouts (and more conversions) because of FIDO enabled payment instruments;

  • Banks will reduce risk and costs while providing Consumers a better experience in interacting with the Bank when they use FIDO for all interactions with the Bank - not just for Merchant transactions (at sites that might have FIDO enabled).

By not thinking of the bigger picture, Banks and browser manufacturers might unnecessarily complicate the protocol and the process. IMO, it will be more productive for Banks to register Consumers directly - and more securely - while eliminating the need for one more change to the protocol to carry new baggage.

@Firstyear
Copy link
Contributor

I agreed with @arshadnoor here. There is a great risk that over-complication and feature extension to this standard will open us to security issues and undermine the trust that exists in webauthn. Webauthn is intended to be a simple 1:1 authentication mechanism. However it appears banks want to use this as a multi-party distributed trust and cryptographic standard.

As a result, I think it would be better if a parallel standard for banks with multi-party processing and proper documentation of intended workflows is created which can then call into fido tokens instead. This keeps both webauthn and bank operations seperate, and reduces risk of security issues and complexity from becoming part of webauthn.

@cyberphone
Copy link

cyberphone commented Jul 28, 2021

@arshadnoor
Your proposed workflow doesn't work (in a meaningful way...) because the creation of a credential at the bank presumes (if we stick to payments) that you get something back comparable to a virtual payment card. This is not what Google & Co plan to ship later this year: consumers still have to manually type in card data and hand it over to merchants which in turn through certified and pretty complex software and services can deduct the origin of (in order to carry out an authentication through the actual issuer).

Fortunately Chrome and other browsers support "deep-links", permitting banks to deploy native applications that make on-line payments comparable to current PoS payments. These solutions also work (using the same virtual payment cards) for PoS payments making this one-time registration + download of app much more acceptable. In fact, the very same app is typically also used for login as well. But it doesn't stop there. In some more developed parts of the world, banks want to use their already existing account-to-account payment networks such as SEPA. This is incompatible with Google's take on the matter since there are no physical cards to read account data from. The mentioned native apps therefore build on a "wallet" concept, like Apple:
https://vipps.io/about-us/news/mobilepay-pivo-and-vipps-join-forces-to-create-one-strong-mobile-wallet/

@akshayku
Copy link
Contributor

@agl

Can an RP say that it does not want any other website to be able to invoke create command for them? Or only a allowlist of RPID that it control? And by default there should be no-one else who should be able to create a credential for another RP.

Also this enforcement must be at the creation level before invoking the create() API. Potentially in addition, server must also be able to verify at it's level while evaluating credential creation response.

This has security implications, and then the question becomes is why user cannot go to the bank and create the credential there. Is the issue is that merchant does not know what kind of bank credentials user has?

@cyberphone
Copy link

This has security implications, and then the question becomes is why user cannot go to the bank and create the credential there.

@akshayku The assumption is that requiring users to go to the bank to get their payment credentials would hamper adoption.

@agl
Copy link
Contributor Author

agl commented Jul 28, 2021

If they have to implement FIDO for their own users to interact with them directly, why would they not simply require that the Consumer register with them first

We are thinking in terms of the world outlined in #1637: consider a person who has their banking app on their phone and thus has a WebAuthn credential on their phone. When performing a transaction on their desktop the bank can request an assertion and, with the existing support for cross-origin assertions and phone support coming to browsers soon, will be able to confirm on their phone. But the bank can't offer to register the local computer for future transactions because there's no cross-origin registration. Using the platform authenticator on the desktop is preferable to having to pull out a phone each time, but the guideance would have to be something like "Go to bank.com and figure out how to add an authenticator in settings".

Can an RP say that it does not want any other website to be able to invoke create command for them?

It's not another website invoking it for them, it's the site itself invoking it in an iframe. If the site has lost origin integrity (e.g. due to an XSS) then, ignoring the probably worse things that result, the create() call could be made, but the clientDataJSON would indicate that it was done in a cross-origin context. The backend could then reject it.

(But note that, if the site can be XSSed then an attacker can trigger a top-level navigation and likely to the same thing today, and in a same-origin context.)

@ve7jtb
Copy link
Contributor

ve7jtb commented Jul 28, 2021

Going back to @agl's issue.

Is this:
a) proposing that a site can create an iframe with the feature-policy publickey-credentials-create to allow the origin of the iframe to make a credential? If so I support that. There are situations like 3dSecure where the ACS is not the bank itself and needs to register a separate credential. There are lots of other places where a SAAS IDP embeds an iframe on a enterprise login page to do authentication. The problem as I think Duo pointed out is that offering to register a platform authenticator for next time won't currently work without doing a full page redirect that may take the user out of the flow they are expecting.

b) per Dirk's proposal on payments. Allow a site in a full page redirect to create a non-discoverable credential for a third site. I see a lot of uses for that and would like to explore if there are any security/privacy issues with doing that.

@agl
Copy link
Contributor Author

agl commented Jul 28, 2021

Is this proposing that a site can create an iframe with the feature-policy publickey-credentials-create to allow the origin of the iframe to make a credential?

Yes, this one.

@nadalin nadalin added this to the L3-WD-01 milestone Jul 28, 2021
@agl agl changed the title Cross-origin credential creation Cross-origin credential creation in iframes Jul 28, 2021
@cyberphone
Copy link

@agl The de-facto standard for mobile to desktop interaction is QR code. Using the aforementioned (in Europe and China already deployed) native mobile apps, you open the application, point to the QR, receive the request on the mobile, and then authorize. You never have to type in card numbers etc. This system typically also works without modifications at the PoS terminal.

Regarding 3DS, due to the PSD2 regulation EU banks have been forced implementing support for SCA (Strong Customer Authentication). That is, you are already enrolled when you get your mobile application. There is no PSD2 in the US but given the fact that it took the US 10 extra years to get chip-card support compared to the EU, we are on very slow train.
@wseltzer

@cyberphone
Copy link

QR is primitive? Sure, but NFC which once was a part of the PC specification (and sometimes even shipping) was effectively "ostracized" due to a lack of foresight by the W3C: w3c/web-nfc#140

@arshadnoor
Copy link

arshadnoor commented Jul 29, 2021

We are thinking in terms of the world outlined in #1637: consider a person who has their banking app on their phone and thus has a WebAuthn credential on their phone. When performing a transaction on their desktop the bank can request an assertion and, with the existing support for cross-origin assertions and phone support coming to browsers soon, will be able to confirm on their phone. But the bank can't offer to register the local computer for future transactions because there's no cross-origin registration. Using the platform authenticator on the desktop is preferable to having to pull out a phone each time, but the guideance would have to be something like "Go to bank.com and figure out how to add an authenticator in settings".

There are 3 problems with this use-case that do not make it compelling enough to complicate FIDO, Adam:

  1. If someone already has a FIDO credential on their phone registered to their bank, 99.99% of people will initiate and complete whatever transaction they want to do, on their phone;
  2. Given Microsofts and Apple's direction wrt FIDO, and given Google's support for FIDO since Android 8, in less than 2 years, I anticipate the vast majority - if not all - of consumer devices will be FIDO ready/enabled;
  3. The last bridge that makes FIDO universal is the problem this cross-credential creation issue is trying to solve: enabling someone who has FIDO on one device to register another platform device with the same RP. IMHO, based on what I've seen in SE Asia, I agree with @cyberphone, QR codes are the simplest, easiest way to solve this problem:
  • Consumer registers "genesis" FIDO credential on phone with Bank;
  • Consumer requests Bank app for a QR code to register another platform - say a desktop PC;
  • Bank app generates and displays encrypted, digitally signed QR code on phone, with whatever the Bank needs to assure itself of the authenticity, confidentiality and integrity of information in QR code;
  • Consumer uses desktop browser to go to Bank website;
  • Consumer clicks on a button on the Bank's home-page that says "Register your device with QR code";
  • Camera on desktop is activated by browser and prompts for QR code;
  • Consumer displays QR code on phone to desktop;
  • Desktop reads, decrypts and verifies QR code;
  • Browser prompts Consumer for "gesture" to register desktop with Consumer's account.

To unnecessarily complicate the FIDO ecosystem for something as simple as this with iframes, caBLE, syncing, etc. seems like taking a sledge-hammer to swat a fly. If the QR code scheme I've outlined is too complicated for banks to handle, perhaps they can start giving out FIDO Security Keys to customers (reprising the "toasters" of a bygone era) to those who are QR code-challenged.

@cyberphone
Copy link

@agl @arshadnoor Widely deployed mobile payment systems pretty much all use the phone as a virtual payment terminal (regardless of scenario), rather than as an authenticator. AFAICT, caBLE doesn't address the virtual payment terminal concept.

@cyberphone
Copy link

A further complication with respect to FIDO/WebAuthn is that current "mobile first" consumer banking solutions predominantly use OOB methods like QR code or push notifications for dealing with desktop Web authentication.

@agl
Copy link
Contributor Author

agl commented Jul 31, 2021

QR codes are the simplest, easiest way to solve this problem

From the perspective of the Web Authentication group, a solution that assumes that RPs have to have a native app shouldn't be satisfying. And, if we're building an authentication scheme, having a big chunk where RPs are expected to build their own solution feels like a gap.

Consumer displays QR code on phone to desktop

Desktops with cameras are far from ubiquitous. Rather I expect the QR would be shown on the desktop and scanned with a phone. But WebAuthn can do better than QR scanning with a native app. WebAuthn to a phone requires proximity (usually via BLE) and so sites that try proxying a QR image won't work.

To unnecessarily complicate the FIDO ecosystem

Above, John asked whether this issue was just about allowing create() in iframes. It is, but the question suggests that it wasn't sufficiently clear. While the implications of enabling creation in iframes should be considered, the actual change is tiny. WebAuthn already supports assertions from iframes so this is just changing the ancestor requirement on create().

@arshadnoor
Copy link

From the perspective of the Web Authentication group, a solution that assumes that RPs have to have a native app shouldn't be satisfying. And, if we're building an authentication scheme, having a big chunk where RPs are expected to build their own solution feels like a gap.

Seems to me that that boat has sailed - Google Play shows 250 mobile banking apps for the US, 100 for India, 50 for Singapore alone, 100 for South Africa, ... Apple claims a total of 2M apps in their app store with Statista claiming nearly 3M for Google Play. I cannot even count 20 passwordless FIDO sites all over the world.

Desktops with cameras are far from ubiquitous. Rather I expect the QR would be shown on the desktop and scanned with a phone. But WebAuthn can do better than QR scanning with a native app. WebAuthn to a phone requires proximity (usually via BLE) and so sites that try proxying a QR image won't work.

The post-pandemic world has changed that, IMO. The scheme I've outlined works between any 2 devices - not just mobile to desktop. I've made the assumption that RPs will build in additional security controls rather than accept just any QR code shown to them (even if encrypted and signed).

the actual change is tiny. WebAuthn already supports assertions from iframes so this is just changing the ancestor requirement on create()

I agree the change is tiny for the browser manufacturer - but I fear the Consumer will end up bearing the consequences of a third-party creating a credential using a protocol that was only intended for a two-party interaction. I would not be surprised if new forms of tracking individual users surfaced, with iframes requesting assertions from such credentials all over the internet - with facial recognition UVMs, the Consumer doesn't even have to do anything to accept the challenge - they're already looking at the device!

Once you open that doorway, it doesn't imply that only legitimate sites and ethical people end up using it.

@cyberphone
Copy link

@agl I don't have a strong opinion about the technical part of this issue, I rather looked on the motives. This observation by @arshadnoor

Seems to me that that boat has sailed - Google Play shows 250 mobile banking apps for the US, 100 for India, 50 for Singapore alone, 100 for South Africa, ... Apple claims a total of 2M apps in their app store with Statista claiming nearly 3M for Google Play. I cannot even count 20 passwordless FIDO sites all over the world.

indicates that getting under the skin of consumer (aka retail) banking will be anything but simple and fast. Personally I think it could be worthwhile to do something which this lot CANNOT DO as a complement to waiting for the deprecation of already sunken (and ongoing) investments supporting pretty well functioning software and services.

Leaving the discussion here. GitHub have an option called discussions that would be more appropriate.

@jcemer-stripe
Copy link

jcemer-stripe commented Aug 2, 2021

Just to reiterate on the initial ask, Stripe is a PSP that participates in Web Payment WG and we found that enrolling credentials from a cross origin iframe is useful for payments use case.

There are different situations where a payment is performed in a cross domain iframe most commonly while requiring 3DS authentication. The 3DS authentication is traditionally performed using SMS OTP, previous transactions recognition or a password. From an issuer perspective, the card is initially enrolled to be authenticated no matter the user device. Allowing WebAuthn credential enrollment in a cross domain iframe allows issuers to enroll cardholder credentials right after a successful traditional 3DS authentication without relying in popups or redirecting the user to the bank website.

@FlxMgdnz
Copy link

FlxMgdnz commented Aug 2, 2021

b) per Dirk's proposal on payments. Allow a site in a full page redirect to create a non-discoverable credential for a third site. I see a lot of uses for that and would like to explore if there are any security/privacy issues with doing that.

@ve7jtb Hi John, has there been any update on Dirk's proposal lately? May be an issue here that I missed so far? Thank you.

@rsolomakhin
Copy link

Allow a site in a full page redirect to create a non-discoverable credential for a third site.

That's not what is being proposed here, is it? Only RP should be able to create a credential for itself. The proposal is for the RP to be in an iframe instead of top-level context. Sorry if I'm not understanding the "third site" comment.

@arshadnoor
Copy link

While I do not deny that everybody benefits from Transaction Confirmation, there are many non-technical issues that need to be considered (some of which I highlighted earlier in this thread). But, here is another one.

Have Banks, PSPs and browser manufacturers given any consideration to how they will comply with GDPR and CCPA regulations wrt providing notice of consent to collecting personally identifiable information (PII) when registering FIDO credentials? While I am not a lawyer, I would consider a credentialId PII since it does uniquely identify a specific individual to an RP. Among other information, CCPA considers a Consumer's "..unique personal identifier, online identifier, internet protocol address, email address, account name, .." PII.

GDPR's Article 7 and CCPA's Section 999.305 have explicit statements on how a Consumer must be notified of the collection of PII and how consent must be received by the party collecting that data. In a cross-origin iframe (as shown in sample screenshots for SPC), the prompts would definitely not comply with the law in my non-legal opinion - the Consumer doesn't even know they're dealing with a third-party RP in the iframe! While the card may be initially enrolled to be authenticated, generating new credentials with a credentialId that uniquely identifies the Consumer is a different transaction/matter.

A second consideration: in the event the Consumer's privacy is breached - not the Private Key, of course, but just the uniquely identifying credentialId - who is responsible for this breach?

  • The Bank that registered the Consumer's credential in the iframe?
  • The Merchant/PSP that enabled the iframe to collect the PII? or
  • The browser manufacturer that facilitated the Merchant/PSP and the Bank to collect the PII?

@cyberphone
Copy link

@arshadnoor From the current spec:
The credential ID could be used as a tracking vector, but to obtain it from the Relying Party the merchant already needs an as-strong identifier to give to the Relying Party (e.g., the credit card number).

That is, 3DS-inspired systems like SPC depend on the user handing over a GUID linked to the user to every third-party (e.g. merchant), he/she interacts with.

Absent from the spec: To secure this process, associated third-party software must be certified and third-parties must be fitted with TLS client certificates in order to access the complex and sensitive support systems required by card not present (CNP) schemes. This obviously doesn't scale well so SPC-based payment processes would in most cases likely be outsourced to payment providers like Stripe or to e-commerce hosts like Shopify.

@arshadnoor
Copy link

I am familiar with that statement in the spec, Anders (@cyberphone); but, in that transaction the Merchant is attempting to get an assertion from the Consumer. What we're discussing here is the creation of a credential. Without GDPR/CCPA like notices and consents at the time PII is created/collected, the transaction could be deemed in violation of the laws.

Additionally, the following sub-article of GDPR Article 7 indicates Merchants/PSPs cannot coerce Consumers into registering FIDO credentials - but Banks could if they changed their terms and required FIDO registration before the payment instrument was used.

4. When assessing whether consent is freely given, utmost account shall be taken of whether, inter alia, the performance of a contract, including the provision of a service, is conditional on consent to the processing of personal data that is not necessary for the performance of that contract.

@ncthbrt
Copy link

ncthbrt commented Aug 4, 2021

Copied over from #1336. Thanks to @emlun for the link to this issue.

I'm a bit saddened by this decision to not allow credential enrolment from the context of an iframe. I'm the CTO of a new payments company (https://stitch.money), which is aiming to improve the payments experience of account to account transfers in our markets.

As @btidor-stripe and @jcemer-stripe mentioned, 3d Secure is a good example of where allowing iframe credential enrolment would be hugely advantageous for the security of the payments ecosystem, but it goes beyond just 3d Secure.

For many of our clients, Stitch offering a more integrated experience, rather than forcing users to do a redirect is an important product feature. Our clients are generally already trusted e-commerce brands/fintech services, and they wish to leverage their brand equity as much as possible in the payment process.

In order to prevent our customers from having to shoulder a large part of the PCI, compliance, and general infosec burden, we deliver the embedded version of our interface via an iframe so that our customers do not have the ability to handle the credentials themselves. I'd venture to say that this is quite a common approach in the industry at large.

For our product, we perform tokenisation of user credentials to streamline subsequent checkouts, and currently have to store this single use token in localStorage. This isn't the best as this value could conceivably be exfiltrated from local storage and used on another device. It'd be greatly preferable if we could use Web Authn as an alternative to these tokens.

I'm a little unclear as to why the enrolment is considered a significant privacy threat in the model (privacy seemed like the original motivation for restricting this functionality), does both retrieval and enrolment not require user interaction? If that is indeed the case, surely this would not be a particularly attractive fingerprinting method? Or is it because some of the associated parts of the API increase the available entropy that could be used in general fingerprinting methods?


With regards to GDRP, the approach I described above actually is to my understanding friendlier to GDPR and GDPR equivalent data protection regimes, as it means our clients don't need to store a token/identifier on their side to allow repeated payments.

We of course design our flow and mandate that our customers do the same to make sure that the appropriate disclosures and consents are made.

Out of necessity, we need to store certain pieces of PII as is to provide our services, and this would not change regardless of whether we enrolled credentials or not.

@arshadnoor
Copy link

The issue to the best of my knowledge, Natalie (@ncthbrt), is that the schemes devised in the past to authenticate Consumers to Issuers, excluded the use of public-key cryptography (PKC) as an authentication mechanism. While PKC schemes can be designed to be used in embedded mode (as S/MIME does), the FIDO/WebAuthn protocol was not designed with this requirement.

FIDO was designed to be a 2-party protocol - like TLS ClientAuth - but with additional features and constraints. Trying to shoehorn that protocol into a multi-party transaction with a third-party controlling the flow was not a design-requirement. When you add in the fact that the world has changed wrt privacy (with GDPR/CCPA simply representing the vanguard of privacy regulations), you have additional non-technical constraints placed on the protocol.

IMO, these constraints can be addressed by simply having Consumers register their payment instrument directly with the Issuer before they use it anywhere. Not only does it eliminate the multi-party FIDO registration conundrum, but the registration flow can be designed to comply with privacy regulations adequately (once the Issuer's lawyers are involved in the process).

Once registered, as long as the Issuer has received consent from the Consumer for that credential to be used (for generating digital signatures) through the Issuers' affiliates, getting an assertion through an iframe is not as problematic - as long as we have ethical Issuers and Merchants/PSPs.

@rsolomakhin
Copy link

getting an assertion through an iframe is not as problematic - as long as we have ethical Issuers and Merchants/PSPs.

@arshadnoor - Out of curiosity, what kind of attacks on FIDO/WebAuth become available with unethical issuers, merchants, and PSPs or in 3rd party contexts?

@cyberphone
Copy link

@arshadnoor

Which credentials are you referring to here? For passwordless FIDO/WebAuthn authentication, there is nothing for the Consumer to type in.

For 3DS you type in the card number since this is how you find out the issuer URL. AFAICT, the card number is the only information shared between the merchant and bank during credential creation using this proposal. In reality, due to the cumbersome backend support required, the entire payment operation must in most cases be outsourced.

@ncthbrt
Copy link

ncthbrt commented Aug 5, 2021

Apologies @arshadnoor if I was a little unclear.

The main thrust that I was trying to convey for our use case, was that we don't want to use FIDO for third party authentication (i.e. acting as an intermediary for the issuer and user), but rather to use it for first party authentication between Stitch and the user.

Our challenge is that due to the nature of the payments business, there is a massive incentive for the payment service providers to be as unobtrusive as possible. We don't want to have to perform a redirect away from our customer's check out flow just to enrol a user, when the only time that the user world ever realistically interact with our systems is when making a payment.

Concrete examples of the type of experiences that we'd like to innovate on include:

Fast

https://fast.co
In the demo on their site, you can see that they give the user the option to pay or sign up for a Fast account from within a modal dialogue. This is still using the traditional username/password flow. We'd like to replace this with a passwordless approach and streamline enrollment to just a click.

My Plaid and Plaid US

https://my.plaid.com/
https://plaid.com/demo/?countryCode=US&language=en&product=transactions
Plaid is a well known entity in the bank account data and account to account payment initiation space.

Plaid Link (seen in the demo) is a single sign on for banks that for their customers is delivered as a modal overlay. This overlay is where users will interact with Plaid for the first time.

My Plaid is a feature on their platform that allows end users to review and revoke permissions granted to various applications that use Plaid's platform for a user's set of bank accounts.

What's unfortunate about My Plaid in my opinion is that it requires that users sign up for a My Plaid account, and then sign in to every other banking institution they use just to revoke access to an app. A much better experience would be to enrol the user's device using Web Authn, and then users can manage permissions based on bank accounts they've previously linked on the device, without the friction of having to create a whole new Plaid account just for the purpose.

Ozow PIN

https://ozow.com/why-ozow/ozow-pin/
Ozow is a payment initiation product that's quite popular in the South African market.

It recently launched the Ozow PIN feature which allows users to quickly make payments without having to re-enter their banking credentials if they'd previously made a payment on their device by entering a PIN code optionally set after the first payment.

To provide this functionality, Ozow makes use of cookies and local storage to store the identifier for the device. This is probably the clearest example of where WebAuthn/FIDO would be a fantastic substitute for this PIN functionality, providing both real security and experience improvements.

@arshadnoor
Copy link

I think its a little clearer now, Natalie (@ncthbrt). What you want to do is register a Consumer's FIDO credential to your site after the Consumer has completed a transaction successfully on your site within the primary frame/top-level window (if my terminology is right). This is not only feasible, but is encouraged by the standard.

The issue being discussed in this thread is to support the creation of a FIDO credential for the ultimate Issuer of the Consumer's payment instrument - perhaps, a credit card - while the Consumer is at the Merchant site. In such a scenario, the Merchant is not the RP for that credential - the Issuer is; and the interaction between the Consumer, the FIDO Authenticator and the Issuer is occurring through an iframe embedded in the Merchant's site.

While such direct interaction with the Issuer is technically feasible, there are legal requirements within GDPR and CCPA that require the ultimate RP to provide notices in a specified manner to the Consumer, and to receive unequivocal consent from the Consumer for providing the PII (the credentialId) to the RP.

In your use-case (as I understand it), the Consumer is registering their FIDO credential with you - hopefully, in the primary frame/top-level window. If you are attempting to register such a credential within an iframe embedded in your customer's (Merchant's) site, then you have the same legal obligations as the Issuer of the credit card.

@ncthbrt
Copy link

ncthbrt commented Aug 5, 2021

Your last sentence describes exactly what we'd like to be able to do @arshadnoor.

Can your legal concerns with this be solved technically, or by displaying the appropriate disclosures on both the merchant and issuer's parts of the interface?

@arshadnoor
Copy link

These are not my concerns, Natalie - they are the law in the EU and California - at least, this is what I've paid attention to so far. :-) I know there are many more privacy laws all over the world - here are 2 sites that are helpful in tracking them: in the US, and globally.

Article 7 of GDPR and Section 999.305 of CCPA speak to an RP's responsibilities regarding disclosure to, and consent from the Consumer. WRT the mechanics and compliance with the entire law, you should really be speaking to your lawyer(s) about this.

@ncthbrt
Copy link

ncthbrt commented Aug 5, 2021

To rephrase: Do GDPR and the like really act to prevent this technical proposal from moving forward? If so, is there changes or controls that could be made to the proposal that could still allow for compatibility with GDRP?

@arshadnoor
Copy link

I don't think the Authorities responsible for enforcing GDPR "prevent" any proposal; they expect businesses to understand the law and comply with it (and consult with their legal team if they don't understand it). They do, however, act to penalize companies who have violated the law: see https://www.enforcementtracker.com/

If you sort on the Fine column in descending order, you should see some very interesting numbers - the most recent fine was for 746M Euro, levied against Amazon two weeks ago for GDPR violations. The top 9 fines levied were over 10M Euro each with the top 30 fines over a million Euro each.

@ncthbrt
Copy link

ncthbrt commented Aug 6, 2021

I don't think the Authorities responsible for enforcing GDPR "prevent" any proposal; they expect businesses to understand the law and comply with it (and consult with their legal team if they don't understand it). They do, however, act to penalize companies who have violated the law: see https://www.enforcementtracker.com/

If you sort on the Fine column in descending order, you should see some very interesting numbers - the most recent fine was for 746M Euro, levied against Amazon two weeks ago for GDPR violations. The top 9 fines levied were over 10M Euro each with the top 30 fines over a million Euro each.

I understand that GDPR enforcers don't prevent a proposal in and of itself. But GDPR concerns around the issue of "credential creation from within an iframe" were raised, so I am merely asking what is the answer to this question:

If site https://example.com/pay-now is embedded as an iframe in a merchant's site, and wishes to create a credential, solely for example.com's use, how is this legally different from redirecting them to example.com and creating it as a first party, then redirecting back?

I may not be understanding the concern, but our lawyers are happy with the current approach we've taken, so I'm pretty certain they would be equally happy with the extra layer of protection we'd be able to provide were this proposal to be taken forward.

@arshadnoor
Copy link

If site https://example.com/pay-now is embedded as an iframe in a merchant's site, and wishes to create a credential, solely for example.com's use, how is this legally different from redirecting them to example.com and creating it as a first party, then redirecting back?

To the extent the iframe displays content that identifies the RP with whom the Consumer is registering their FIDO credential, and the RP provides notices/services required of data controllers before receiving consent, as described in GDPR Article 7, it is conceivable the two flows may not be legally different. But, I'm not qualified to make that legal judgement.

My objection to the "feature-creep" of FIDO/WebAuthn is that, to the best of my knowledge, there isn't a single passwordless FIDO2 site (in production use) visible on the internet yet, so there is a lot for all of us to still learn about the protocol and its gaps as it gets adopted in scale. But, if we keep adding features to it that run up against regulations - when many us laboring on FIDO adoption are just trying to eliminate passwords, OTP, KBA and all the crap billion/trillion dollar companies trot out as security - we might kill FIDO before it can even stand on its legs. It is complicated enough already.

P.S Apologies for the rant, but I've been personally working on passwordless strong-authentication since 1999 and would like to see my 4-year old grandson use it as a matter of course for everything he accesses before I leave for the bit-bucket in the sky. But, if we don't focus on making FIDO simpler, easier and more cost-effective than legacy authentication schemes, this may be another lost opportunity. I will make this my last post on this topic as I feel I've consumed enough bandwidth on this thread. Thank you all for your indulgence.

@cyberphone
Copy link

@arshadnoor Regarding timing: It took Google and the W3C five years to figure out that https://www.w3.org/TR/payment-handler/ does not meet the market's expectations, and finally remove it from the charter: https://www.w3.org/Payments/WG/charter-2021.html

@ncthbrt
Copy link

ncthbrt commented Aug 9, 2021

Just to move this conversation back on track, I'd like to reiterate what @emlum said:

I don't think any multi-party transaction has been proposed here. The proposal is not to allow site A (merchant) to register credentials on behalf of site B (payment provider), rather that site A may embed site B in an iframe, in which site B may register credentials for site B. Communication between the user and site B will be direct and not pass through site A on the way (i.e., public keys and identifiers will not be exposed to site A), and site B is in full control of the registration ceremony just like it would be with a full page redirect.

At least for our use case, and to my understanding, Stripe's use case, this is true. I think this change request may have been conflated with a more complicated, knottier ask (multi-party credential sharing) that may indeed not be in scope for WebAuth.

@davordavidovic
Copy link

At Adyen our use case also depends on the use of cross-origin credential creation in iframes from a payment aspect. A lot of our merchants are integrated in a redirect flow in which they host our page in an iframe. Our use case is identical to the ones outlined by @ncthbrt and probably for most PSPs.

@stephenmcgruer
Copy link
Contributor

stephenmcgruer commented Aug 18, 2022

TL;DR - the Web Payments WG would like to propose allowing credential creation in a cross-origin iframe, as long as the iframe has both a publickey-credentials-create permission policy and a user activation (e.g., click).

Hi folks,

On behalf of the Web Payments Working Group, I am reaching out to reopen the discussion around allowing credential creation in a cross-origin iframe. (More accurately, in a browsing context that is not same-origin with its ancestors).

To be clear from the start (since this has been a confusing point), the intention is to allow for the following setup:

  1. The top-level frame is https://merchant.example/
  2. The top-level frame embeds an iframe to https://psp.example/.
  3. Within the https://psp.example/ iframe, psp.example takes the user through some authentication flow (to their own standards), e.g., username/password.
  4. Once psp.example is happy they have authenticated the user to their liking, they wish to create a WebAuthn credential for the user in order to provide a smoother experience in the future.
    1. JavaScript code within the https://psp.example/ iframe calls navigator.credentials.create({publicKey:...}), which (after the usual flow) creates a credential for psp.example.

There is no creation of a credential for another origin.

(Note that the above example implies a Payment Service Provider (PSP) being involved; one could equally imagine a bank doing similar, e.g. replace psp.example with bank.example).

We have heard from many payment industry folks, both on this issue and in the WPWG, that enrolling users within an embedded flow is important to them. In the payments world, not breaking the ongoing payment is critical to a good user experience, and so there is a delicate balance to walk when trying to improve for a future good experience (that is, by enrolling the user's authenticator device).

From this thread and its precursor, we have heard the following concerns:

  1. There is an existing tracking concern with cross-origin get(), in which a tracker may track a user that is visiting another top-level website by initiating navigator.credentials.get() from a cross-origin iframe, and trick the user into completing it.
    1. This concern already exists today, but we acknowledge it is made worse by allowing create() in a cross-origin iframe, as the user would no longer need to have visited the tracker in a top-level frame previously (in order to enroll the credential) - the tracker could begin the attack directly from an iframe.
    2. For this, our proposal (see below) includes an additional requirement of having a user activation (e.g., click) when creating a credential in a cross-origin iframe. This does not fully defeat the attack, but does raise the bar to a level we hope is acceptable.
  2. That regulations may have requirements around the gathering of personally identifiable information and obtaining user consent for such.
    1. With respect, we do not believe this is relevant to the technical ability to add this feature to the specification. Each company that uses this feature would be (as always) responsible for ensuring that they meet regulatory requirements.
    2. There is also nothing that stops the embedded content from informing the user and collecting user consent. They can render privacy policy links, user consent dialogs, etc, all in the embedded iframe.
  3. That credentials shouldn't be creatable for a different origin than the current one.
    1. We completely agree. That is not this proposal, nor what this issue was ever about - we believe that was a mistaken understanding.

The Proposal

Allow the creation of a WebAuthn credential in a frame in which sameOriginWithAncestors is false, if and only if:

  1. The frame has a publickey-credentials-create permission policy set on it, AND
  2. The frame has a user activation

The first of these requirements protects the top-level frame against malicious iframes. The second of these requirements attempts to protect the user against a compromised or collaborating top-level frame allowing an iframe to try and trick the user.

Draft PRs adding this support can be found at #1 and #2, though we encourage their use only as a clarity aid rather than a finished product.

It may also be reasonable for the client or authenticator device to make it clearer to the user that the credential creation is happening in an embedded context. For example, the client may have text like "rp.example, embedded in merchant.example, wants to verify your identity". We think that the WebAuthn specification allows for clients to do this already if they wish, but if not we would be happy to see WebAuthn (or FIDO) expanded to allow this.

FAQ

What if I (an RP) don't want to create credentials in an iframe?

Firstly, and to be clear again - this proposal is only allowing the RP to initiate credential creation inside an RP-origin iframe, so it is the RP's code that is choosing to call create().

If the RP is concerned about themselves doing so 'accidentally', e.g. if a website puts the RP inside an iframe when they are not expecting it, they have three options:

  1. Serve their content with an X-Frame-Options header of either DENY or SAMEORIGIN, which will stop their content from being embedded this way.
  2. Attempt to detect whether they are in a cross-origin iframe via JavaScript before calling create(). (There are a variety of ways to do this checking, and I don't want to endorse any particular option as the 'correct' way!)
  3. After creation of the credential, check the crossOrigin member of the returned collectedClientData. This will be true if the create() call was within a cross-origin iframe.
    1. Note that this is an after-the-fact check, and so may still have had consequences, e.g. if the RP was creating a discoverable credential (it may have overridden a previously existing credential on the authenticator device).

@spencercap
Copy link

is this implemented and supported now?

if so, how do i use it?
like...

<iframe src="..." allow="publickey-credentials-create *" />

or

<iframe src="..." allow="publickey-credentials-create" />

and if i'd like to enable multiple allows on the iframe, is it this?:

<iframe src="..." allow="publickey-credentials-create *; publickey-credentials-get *; clipboard-write" />

gave the above a go in chrome 112 and i'm getting this error:
200/signup/start:1 Uncaught (in promise) DOMException: The following credential operations can only occur in a document which is same-origin with all of its ancestors: storage/retrieval of 'PasswordCredential' and 'FederatedCredential', storage of 'PublicKeyCredential'.

@stephenmcgruer
Copy link
Contributor

is this implemented and supported now?

It is now in the webauthn spec, however no browser has implemented support yet. Chrome is tracking implementing it in https://crbug.com/1420639 and we hope to implement during Q2 (but no promises on timelines I'm afraid!).

@mangoplane
Copy link

Is this supported by any browsers yet, say Firefox? It appears Chrome is still underway with resolving this issue. Cheers.

@mangoplane
Copy link

mangoplane commented Jun 13, 2023

Until this gains wider support, is this a recommended Webauthn flow when given as a service for another origin to use?

Creation:

  1. Register credential. Open new browser window that matches the RP Origin (e.g. auth.example.com). In this opened window, register the users authenticator by creating a new credential.
  2. Finishing by returning some token representing their logged in session via window.open postMessage.
    e.g.
// Within auth.example.com
window.opener.postMessage({ type: 'SESSION', token: 'sessionToken' }, 'https://original.example.com');

Assertion:

  1. Similar to the above, OR an iframe with the publickey-credentials-get ORIGIN permission so that you can have the RP cross-origin in a clean iframe.

AFAIK this will work fine, and is secure particularly if I pass the sessionToken back to the invoking site via a shared secret created with Diffie-Hellmann.

This should allow for a fairly effortless migration once the above publickey-credentials-create permission for iframes becomes widely supported at the browser level.

Kind regards.

@timcappalli
Copy link
Member

timcappalli commented Jun 13, 2023

@mangoplane please use FIDO-DEV for implementation discussions. This repo is for spec work.

moz-v2v-gh pushed a commit to mozilla/gecko-dev that referenced this issue Aug 18, 2023
…veditz

This implements publickey-credentials-get in Permissions-Policy. This allows for cross-origin
credentials.get() which is currently only possible in Chrome. This is similar to D42445 but
uses the correct name from https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Permissions-Policy#directives
Credential creation is not touched since there is no specification for it yet:
w3c/webauthn#1656

Differential Revision: https://phabricator.services.mozilla.com/D174108
ErichDonGubler pushed a commit to ErichDonGubler/firefox that referenced this issue Aug 18, 2023
…veditz

This implements publickey-credentials-get in Permissions-Policy. This allows for cross-origin
credentials.get() which is currently only possible in Chrome. This is similar to D42445 but
uses the correct name from https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Permissions-Policy#directives
Credential creation is not touched since there is no specification for it yet:
w3c/webauthn#1656

Differential Revision: https://phabricator.services.mozilla.com/D174108
@plehegar plehegar modified the milestones: L3-WD-01, L3-WD-02 Oct 4, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests