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

Prohibit Create Credential from cross-origin iframes #1336

Closed
jcjones opened this issue Oct 28, 2019 · 16 comments · Fixed by #1394
Closed

Prohibit Create Credential from cross-origin iframes #1336

jcjones opened this issue Oct 28, 2019 · 16 comments · Fixed by #1394

Comments

@jcjones
Copy link
Contributor

jcjones commented Oct 28, 2019

(Follow-on to #911 for enabling Feature Policy)

During an internal threat-modeling exercise about cross-origin use of WebAuthn, we were led to question if the utility of permitting the creation of WebAuthn credentials in an iframe was worth the usefulness to a tracker. I believe it is, but that it's simple to raise the difficulty on a tracker without dramatically altering the current processing model. I would like to propose that we specify WebAuthn's Create Credential operation be only callable from browsing contexts that are top-level or same-origin with their ancestors.

Scenario
https://example.com/ directly embeds a script from https://website.tracker/ . The script from website.tracker appends to the DOM an invisible iframe with allow=”publickey-credentials:*”. The embedded script’s origin is https://worldwide.panopticon.tracker/ .

On load, https://worldwide.panopticon.tracker/ uses its database of tracking information to ascertain a finite list of probable WebAuthn credentials, both resident and not-resident, one of which it hopes will correspond to the user. They simultaneously consider the question of whether to attempt to create a new credential, if the probable success is low.

For optimum likelihood of success, https://worldwide.panopticon.tracker/ ‘s script waits for the user to appear to log-in at https://example.com/ , as sites are doing with Push now, then interrupts that flow to start WebAuthn, hoping to confuse the user into following the prompts.

https://worldwide.panopticon.tracker/ ‘s script makes its choice then: attempt a Get Assertion operation, either with an allow list of probable credentials or hoping for resident credentials; or attempt a Create Credential for future use.

Thoughts

If https://worldwide.panopticon.tracker/ doesn't have an opportunity to create credentials in the first place -- at least without becoming a top-level context -- this scenario doesn't provide a mechanism for tracking.

Obviously there are legitimate reasons to permit cross-origin Create Credential, but legitimate sites are likely less concerned with prompting a top-level load than https://worldwide.panopticon.tracker/ would be.

Under this scenario, https://worldwide.panopticon.tracker/ would need to open a pop-up, or cause a navigation, in order to do a WebAuthn enrollment. With pop-ups we have some reasonable controls around requiring interaction. Both of these add more friction than a direct invocation, and as they change the window in some way, they have a stronger likelihood of signalling to the user that the website is different than simply popping over-top of what the user was actually trying to accomplish.

@equalsJeffH
Copy link
Contributor

@jcjones wrote:

I would like to propose that we specify WebAuthn's Create Credential operation be only callable from the top-level context.

Do you actually mean to say "...only callable from browsing contexts that are top-level or same-origin with their ancestors" ?

Because, currently, as spec'd in WebAuthn L1's Section 5.1.3. Create ... Method, one can create creds in contexts that are same-origin with their ancestors (step 2 therein).

The analysis above and your hypothesis of actors being able to create a https://worldwide.panopticon.tracker/ that would behave as discussed sounds nominally plausible. I've found some seemingly-relevant recent conference papers, as well as tech press articles wrt Web Push abuse in the wild, to go digest.

In the meantime I'm interested in others' comments on this proposal.

WRT changes to the WebAuthn spec (post landing of PR #1276) that this issue would cause: in concrete terms, the change would be fairly simple -- it means restoring the check of the sameOriginWithAncestors parameter in [[Create]]() that PR #1276 is removing (i.e., restoring only that check assumes that same-origin iframe usage is actually ok).

@jcjones
Copy link
Contributor Author

jcjones commented Nov 1, 2019

@jcjones wrote:

I would like to propose that we specify WebAuthn's Create Credential operation be only callable from the top-level context.

Do you actually mean to say "...only callable from browsing contexts that are top-level or same-origin with their ancestors" ?

Oops, Yes, I apologize for my lack of rigor there -- I'll edit to be clearer.

@agl
Copy link
Contributor

agl commented Nov 6, 2019

Noting for the record that I've talked with some of our payments people and they would certainly like to be able to enroll platform authenticators inline, during a payments flow, and that would need registration to occur within a cross-origin iframe.

[ see also similar/same use case described by @btidor-stripe, below -- @equalsJeffH ]

@jcjones
Copy link
Contributor Author

jcjones commented Nov 6, 2019

Yes, and at TPAC I believe it was Duo who asked for enrollment in the cross-origin iframe, too.

However, I believe this to be a real threat, and one easily-remedied.

@jcjones
Copy link
Contributor Author

jcjones commented Nov 6, 2019

Example situation with Notifications - image

@kenrb
Copy link

kenrb commented Nov 8, 2019

To briefly summarize what I think is above (please let me know if anything here is off):

  1. The Push API problem is not directly relevant to the cross-origin iframe proposal, but serves an example of how an incidental abuse case can cause harm to users and cause UA implementers to have to roll back capabilities, and so the suggestion is that we should err on the side of caution.
  2. The abuse case here is user tracking in a post-3p-cookie world. A tracking iframe could accumulate user profile across sites if it can do the following:
    a) Induce the user to create a credential for the tracker's origin on their authenticator.
    b) Correctly guess the user's identity when they visit other sites that the tracker is embedded on (or else guess that the authenticator supports resident keys?).
    c) Induce the user to activate the authenticator (UP or UV) on each of those sites. This could confirm the heuristic guess and allow a data point to be added to the profile of the user being tracked.

It's not clear to me that this is plausible, since the high bar for success would limit the amount of tracking data to be gained, and also the abusive behaviour would be easily visible to users and embedding site authors.

Conversely, I do think there are legitimate use cases for MakeCredential in cross-origin iframes. If a payment service is embedded in a merchant, it would not have an easy way to bootstrap users to using WebAuthn, other than doing a full page redirect or a popup, both of which create very high abandonment rates for transactions.

We certainly need to be careful about adding new tracking modes to the web, but at the same time it doesn't seem right to be limiting use cases, and potentially adoption, for the sake of attacks that may not be practical.

@btidor-stripe
Copy link

This issue was mentioned in the Web Payments TF and I wanted to add some color on the payments use case.

If we’re thinking about applying WebAuthn to 3D Secure, it would make the most sense to enroll users inline in the authentication flow. So the user would be making a purchase on a merchant site and go through 3DS authentication with traditional factors like SMS OTP. After they’ve authenticated, but with the 3DS iframe still open, the issuer might notify the user that their device supports WebAuthn and prompt them to enroll a credential for future use.

This kind of inline enrollment flow is attractive for the 3DS use case because the authentication modal is often the issuer’s highest-traffic touchpoint with the user, and because it’s typically a separate and self-contained service that isn’t integrated with the online banking portal or other properties — it can only be accessed when making a payment.

This would all be happening in a cross-origin context: the parent would be the merchant’s checkout page and the child would be the issuing bank’s 3DS authentication service (the "ACS"). For this use case the frame would be visible and I’d imagine there would be an explicit user gesture to trigger enrollment.

@agl
Copy link
Contributor

agl commented Dec 16, 2019

On the call of 2019-12-11, J.C. requested a Google response on this issue (this is built upon @kenrb's response above)

Firstly, we’re not too concerned about similarities to push notifications. The value to the attacker seems significantly smaller: push notifications allow an attacker to induce users to install malware etc, while assertions only allow them to potentially link users across sites. Additionally, the costs to the attacker seem greater: push notifications can be enabled with a single click, while assertions require intrusive UI every time, and for the user to have and touch an authenticator. Another difference is that push notifications are abused by first-party sites while the worry here involves third parties. If third-party embeddings were to start abusing this, first-party sites could always stop embedding them. They might not, but two entities would have to cooperate.

Secondly, the case where a credential ID is specified seems a little far fetched for mass tracking. The set of possible users will be large and, if you can narrow it down sufficiently to guess at specific credential IDs, then the additional information that knowing the right one gives seems small indeed. This point does not hold for resident credentials, however.

On balance, creating credentials does appear to be something that people legitimately desire from within cross-origin iframes and so we are hesitant to eliminate it. Splitting the feature policy into “create” and “get” is obviously useless when top-level and subresource origins are colluding so would only be useful if delegating only one ability is useful. Our feeling is that detailed API filtering isn’t in the style of Feature Policy, so we lean slightly against this unless the WG doesn’t wish to support “create” initially. There might be cause to prohibit resident credential creation from within cross-origin iframes but we’re concerned that we don’t fully understand the legitimate use cases well enough to have a firm opinion on this. Also, a platform cannot precisely implement such a prohibition with CTAP2 authenticators.

Overall, we’re thus supportive of continuing to allow both operations in cross-origin iframes, when Feature Policy permits, with the possibility of restricting the creation of resident credentials pending site-operator feedback.

@dlongley
Copy link

dlongley commented Jan 8, 2020

There might be cause to prohibit resident credential creation from within cross-origin iframes but we’re concerned that we don’t fully understand the legitimate use cases well enough to have a firm opinion on this.

Prohibiting credential creation from within cross-origin iframes may limit or prevent "just in time" registration flows that reduce onboarding friction.

@jcjones
Copy link
Contributor Author

jcjones commented Feb 24, 2020

Mozilla believes firmly that Create Credential should be prohibited from cross-origin iframes for Level 2 of the specification.

Once process flows are built around cross-origin creation, we will likely be unable to reconsider this decision without great pain to implementers. As such, there should exist no doubts as to the privacy properties of enabling this capability, yet Mozilla and our community does indeed have such doubts.

It is possible that this might be something we revisit to permit in a future version of the specification, once we have further deployed experience with cross-origin Get Assertion.

@equalsJeffH
Copy link
Contributor

see also issue #1377

@jcjones
Copy link
Contributor Author

jcjones commented Feb 26, 2020

@jcjones to write the PR

@rmondello
Copy link

We’re supportive of this.

@ncthbrt
Copy link

ncthbrt commented Aug 4, 2021

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 in our markets.

As @btidor-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 consideration. In order to prevent our customers from having to shoulder a large part of the PCI compliance burden, we deliver the embedded version of our interface via an iframe so that our customers do not have to directly handle the credentials themselves. This is quite a common approach in the industry at large.

For our product, we perform tokenisation of users 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, 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?

@emlun
Copy link
Member

emlun commented Aug 4, 2021

@ncthbrt This discussion is currently continuing in #1656.

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.

12 participants