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

WebAuthn failing in Chrome for incompatible versions & on modal fail/cancellation #6050

Closed
brainwane opened this issue Jun 19, 2019 · 40 comments
Labels
bug 🐛 cross browser bug 🐛 Issue specific to a particular browser or resolution
Milestone

Comments

@brainwane
Copy link
Contributor

@webknjaz reported:

@brainwane I've tried that on Test PyPI.

So I have a TOTP set up. I clicked on Add 2FA with security key.
It prompted me to enter a Key name which I did (Yubikey Neo).

STR

After that, clicking Provision key does nothing visually. So I've opened DevTools.
I can see a successful GET request to https://test.pypi.org/manage/account/webauthn-provision/options with some JSON payload in the response. It looks legit, contains my user data and a challenge.
After clicking more times on that button, each of them produces an exception being logged to the JS console.
The same happenes on prod PyPI, in incognito mode, with browser extensions disabled.
test-pypi-webauthn-exc

Runtime

Google Chrome
Version 69.0.3497.81 (Official Build) (64-bit)
running Gentoo Linux

Trace
[8] bind-modal-keys.js:43 Uncaught (in promise) DOMException: A request is already pending.
r @ bind-modal-keys.js:43
(anonymous) @ bind-modal-keys.js:43
Promise.then (async)
r @ bind-modal-keys.js:43
(anonymous) @ bind-modal-keys.js:43
Promise.then (async)
r @ bind-modal-keys.js:43
(anonymous) @ bind-modal-keys.js:43
Promise.then (async)
r @ bind-modal-keys.js:43
(anonymous) @ bind-modal-keys.js:43
(anonymous) @ bind-modal-keys.js:43
(anonymous) @ webauthn.js:179
(anonymous) @ webauthn.js:23
r @ runtime.js:55
(anonymous) @ runtime.js:293
t.(anonymous function) @ runtime.js:107
r @ bind-modal-keys.js:43
(anonymous) @ bind-modal-keys.js:43
(anonymous) @ bind-modal-keys.js:43
d @ raven.js:445
[2] bind-modal-keys.js:43 Uncaught (in promise) DOMException: The operation either timed out or was not allowed. See: https://w3c.github.io/webauthn/#sec-assertion-privacy.
r @ bind-modal-keys.js:43
(anonymous) @ bind-modal-keys.js:43
Promise.then (async)
r @ bind-modal-keys.js:43
(anonymous) @ bind-modal-keys.js:43
Promise.then (async)
r @ bind-modal-keys.js:43
(anonymous) @ bind-modal-keys.js:43
Promise.then (async)
r @ bind-modal-keys.js:43
(anonymous) @ bind-modal-keys.js:43
(anonymous) @ bind-modal-keys.js:43
(anonymous) @ webauthn.js:179
(anonymous) @ webauthn.js:23
r @ runtime.js:55
(anonymous) @ runtime.js:293
t.(anonymous function) @ runtime.js:107
r @ bind-modal-keys.js:43
(anonymous) @ bind-modal-keys.js:43
(anonymous) @ bind-modal-keys.js:43
d @ raven.js:445

Originally posted by @webknjaz in #5661 (comment)

@ewdurbin
Copy link
Member

This version of chrome is fairly out of date. Would it be possible to try with a more recent release of Chrome @webknjaz?

@webknjaz
Copy link
Member

It'll take some time for me to get it, but from what I see it should be a bug on JS side unrelated to a browser.

@ewdurbin
Copy link
Member

[2] bind-modal-keys.js:43 Uncaught (in promise) DOMException: The operation either timed out or was not allowed. See: https://w3c.github.io/webauthn/#sec-assertion-privacy.

specifically this log line makes it appear that it's not an issue with JS served by warehouse, but rather on the browser side, as the attestation never completed.

WebAuthn requires browser implementations to "play nicely", and in this case it appears the browser did not ever respond.

Was there a pop over requesting access to the token?

@webknjaz
Copy link
Member

Right. No pop-up. I've just tried on a PixelBook (Chrome 75, ChromeOS==fancy Gentoo) and a pop-up appears there.
Interestingly, I'm able to use my Yubikey with GitHub which probably means that they work around the standard...

/me navigates to the Google Chrome changelog for more details

@webknjaz
Copy link
Member

This suggests that they've added some webauthn support in Chrome 67: https://developers.google.com/web/updates/2018/05/webauthn

@webknjaz
Copy link
Member

So it seems like the better support for Webauthn was introduced around January. It probably makes sense to put a big red warning next to the 2FA setting if the browser is old...

@brainwane
Copy link
Contributor Author

So what's the minimum Chrome version that properly supports WebAuthn, including PublicKeyCredential and any other components we need? Clearly Version 69 didn't, even though there was some WebAuthn support as of Version 67.

@brainwane brainwane changed the title WebAuthn key provisioning (evidently) failing (Chrome on Gentoo) Warn older Chrome users to upgrade to use WebAuthn Jun 19, 2019
@webknjaz
Copy link
Member

https://webauthn.guide/ states this:

As of January 2019, WebAuthn is supported on Chrome, Firefox, and Edge, with upcoming support on Safari.

So probably matching release dates should give proper versions.

@pradyunsg
Copy link
Contributor

pradyunsg commented Jun 19, 2019

There was a stable release of Chrome 72 in Jan 2019. If some wants to, they can investigate to see if this information is available on Google's Chrome Releases blog:

https://chromereleases.googleblog.com/2019/01/

@webknjaz
Copy link
Member

I think this may hit non-Chrome users as well.

@woodruffw
Copy link
Member

They might have changed it since I last checked, but I believe GitHub doesn't actually use WebAuthn for security keys yet -- I believe they're still on U2F via u2f.js. That would explain why they aren't affected.

Chrome 74 on macOS works for me, as does FF latest on macOS. At the risk of speculating idly, maybe it's a CTAP issue with Linux + Chrome? I vaguely remember having to add udev rules when I added my security keys on Linux, so maybe there's other mis-interacting components there. I'll do some testing on my Linux machines this evening.

@webknjaz
Copy link
Member

Nah, that's def on the browser side ;)

@alex
Copy link
Member

alex commented Jun 19, 2019

Google Accounts uses webauthn for login, but not registration.

@woodruffw
Copy link
Member

Just confirmed that it works on Chrom(e|ium) 75 (Ubuntu 18.04).

Chrome 67 was released in May 2018 and WebAuthn Level 1 wasn't formally released until March of this year, so it's entirely possible that we're seeing either the effects of a spec change or just a buggy early implementation. Perusing through the chromium issue tracker, I think the latter is a safe bet.

Either way, it'd be interesting to see what exactly is failing. @webknjaz, would you be able to run a local deployment and insert some catches + logging?

@webknjaz
Copy link
Member

Do you mean that I'd need to run it with a front-end build in dev mode with src-maps?
I don't have warehouse locally, but if needed I can find some time and set up the dev env. It may be faster for you to run some Ubuntu VM from vagrant locally with an old Chrome installed there...

@woodruffw
Copy link
Member

Hey, sorry for the late response. You shouldn't need the source maps, it should be sufficient to just pepper some .catch(...) calls on the promises and see what the actual exception is.

@webknjaz
Copy link
Member

Can I just stick some breakpoints in DevTools then?

@woodruffw
Copy link
Member

Yep, that should also work.

@webknjaz
Copy link
Member

I mean, I should be able to do this in the prod PyPI, right?

@woodruffw
Copy link
Member

Ah, yes. Nothing should be different in prod.

@webknjaz
Copy link
Member

That's better! Because I cannot find time to spin up everything locally right now :)

I thought that maybe it's minimized there.

@webknjaz
Copy link
Member

Hm... It's minified and my browser doesn't pick up srcmaps for some reason.

@ewdurbin
Copy link
Member

This should be resolved, there was a misconfiguration on test.pypi.org that was not present on pypi.org.

Can you attempt to reproduce and update us if it is still not working?

@webknjaz
Copy link
Member

webknjaz commented Jul 7, 2019

@webknjaz
Copy link
Member

webknjaz commented Jul 7, 2019

I was able to set some breakpoints but no success figuring out where the exception happens. Only that it's in some promise...

@webknjaz
Copy link
Member

webknjaz commented Jul 7, 2019

So I set up a local instance. I commented out the whole bind-modal-keys.js but the exception logged in the console still points to that file, to one of the commented lines.

I think that maybe srcmaps aren't generated properly...

@webknjaz
Copy link
Member

webknjaz commented Jul 7, 2019

I have a feeling that some promise hasn't been awaited.

@webknjaz
Copy link
Member

webknjaz commented Jul 7, 2019

I believe that one of the problems is that func(csrfToken) @ https://github.com/pypa/warehouse/blob/0d9c726153394cf6aca178c9015c467707fbaa2e/warehouse/static/js/warehouse/utils/webauthn.js#L47 isn't awaited. But there's more.

@di
Copy link
Member

di commented Jul 11, 2019

After doing some debugging with @webknjaz, I noticed that I can reproduce this exception in modern Chrome as well by simply clicking "Provision key" and then canceling the in-browser modal that appears, so it seems like there's two issues here:

  • we aren't correctly detecting incompatible versions of Chrome
  • we have this exception happening in all versions of Chrome when the modal fails or is cancelled

@di di added the bug 🐛 label Jul 11, 2019
@brainwane brainwane changed the title Warn older Chrome users to upgrade to use WebAuthn WebAuthn failing in Chrome for incompatible versions & on modal fail/cancellation Jul 18, 2019
@brainwane brainwane added this to the OTF Security work milestone Jul 18, 2019
@brainwane brainwane added the cross browser bug 🐛 Issue specific to a particular browser or resolution label Jul 18, 2019
@webknjaz
Copy link
Member

After further debugging, I've found out that if (!window.PublicKeyCredential) { feature detection check is invalid. This function is present in my version of Chrome, that's why I don't get any error messages displayed (the DOM node stays hidden).

https://github.com/pypa/warehouse/blob/1d8e0fa/warehouse/static/js/warehouse/utils/webauthn.js#L163

@webknjaz
Copy link
Member

webknjaz commented Jul 26, 2019

So I've tried https://demo.yubico.com/u2f and https://demo.yubico.com/webauthn .
The first one works and the second works partially. There's an "Internal authenticator" test which doesn't work.

pics yubico-webauthn-demo yubico-webauthn-two

So does Warehouse only implement this internal authenticator type support?

@webknjaz
Copy link
Member

I've noticed there's u2f.getApiVersion() method available. Here's the version in my browser:

> u2f.getApiVersion(console.log)
{js_api_version: 1.1}

If modern browsers have a different one — maybe that's it?

@webknjaz
Copy link
Member

webknjaz commented Jul 26, 2019

Also, this article https://www.ubisecure.com/api/fido-webauthn-api/ suggests using PublicKeyCredential.isUserVerifyingPlatformAuthenticatorAvailable() for the feature discovery:

The isUserVerifyingPlatformAuthententicator method can be used to detect if a platform authenticator that implements user verification exists on the user’s device. This allows the application to improve user experience by only displaying options in the user interface that are sure to exist.

Here's the output for me:

> PublicKeyCredential.isUserVerifyingPlatformAuthenticatorAvailable().then(console.log)
Promise {<pending>}
false

@webknjaz
Copy link
Member

I probably nailed it. Needs testing tho. On the platforms, I don't have. #6264.

@webknjaz
Copy link
Member

I probably nailed it.

Wrong guess...

@woodruffw
Copy link
Member

@webknjaz Can you attempt to repro on master (which should also be live)? #6305 may have fixed this.

@webknjaz
Copy link
Member

webknjaz commented Aug 2, 2019

@woodruffw So I've tried it out locally. Nothing happens on the first click. But when I click [ Set up security device ] for the second time, A request is already pending. error message appears. When I click more, every subsequent click adds another instance of that error message.

            warehouse-webauthn-errors

@brainwane brainwane removed this from the OTF Security work milestone Sep 8, 2019
@brainwane
Copy link
Contributor Author

Contractors on the OTF-funded work need to stop work on the security features in order to ensure we complete the accessibility and internationalization work by the end of the month. Therefore, while this is necessary to get us out of beta for this feature #5661 (comment) , I'm removing it from the milestone.

@webknjaz
Copy link
Member

@woodruffw did you mean to also close this?

@woodruffw
Copy link
Member

Yes! Thanks @webknjaz.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug 🐛 cross browser bug 🐛 Issue specific to a particular browser or resolution
Projects
None yet
Development

Successfully merging a pull request may close this issue.

7 participants