Action: When enrolling and using webauthn with a Yubikey security key or Yubikey 5 NFC, a pin should be required to use the FIDO2 interface for passwordless logins.
tl;dr: On ubuntu 20.04, firefox 78.0.2, Nextcloud 19.01, passwordless login is allowed using only "U2F." Other browsers and OSs work as expected which makes me think this is a bug.
The expected behavior I had was: Login > Key insertion > pin entry > FIDO2 auth > user authenticated. This is safe two factor authentication. Something I have, and something I know.
The behavior noted is: Login > Key insertion > just press the button > authenticated. This is only a single factor... and a weak one.
Upon examining my yubikey with the command line tools, there are no resident credentials saved on the key itself for nextcloud. Meaning, FIDO2 isn't being used as it should for passwordless auth (to my knowledge). It seems to be being used as U2F only.
Upon turning off the FIDO2 interface of my Yubikeys (something that should break FIDO2 logins) I was able to passwordless-auth into my account using only U2F. T
Upon turning off the U2F interface of my Yubikeys (something that should have zero effect on FIDO2) I was unable to passwordless-auth into my account. Thus proving the U2F interface, not the FIDO2 interface is being used for passwordless authentication in this scenario.
This is not the intended use case for the U2F authentication flow to my knowledge. Which results in a weak single-factor login.
Please roast me and tell me i'm wrong. This is the very first GitHub post i've ever made.
Edit: After disabling the FIDO2 module on the Yubikeys, I can "U2F" in to NextCloud without entering a pin for the key on all browsers and operating systems I have access to (Win 10 2004, Ubuntu 20.04, Chrome, FF, Edge).
Disabling the module is a non-privileged action for the key, so that makes it an incredibly simple way to bypass the security benefits of FIDO2 over password + U2F.
technical-details
There should be an option in the settings to make the PIN required.
If I read the source correctly, Nextcloud explicitly sets the verification option to AuthenticatorSelectionCriteria::USER_VERIFICATION_REQUIREMENT_DISCOURAGED, which results in the WebAuthn system never asking for user verification through PIN or Fingerprint.
This should really be configurable through the admin UI, or at worst through config.php...
This issue discussed here: https://hwsecurity.dev/2020/08/webauthn-pin-bypass/
Even when a PIN was asked for when registering, both Microsoft and Nextcloud didn't verify if the actual response sent to the webserver indicated a successful PIN entry.
At Microsoft, they declared it a security vulnerability and fixed it.
At Nextcloud, they disabled PIN entry completely and defined it as intended behavior, therefore condemning security keys to being a single factor only for now.
_(slight rant)_
I don't even think nextcloud warns you to add a second factor if you simply trade a password for a security key. This makes security key theft a real threat. It doesn't even have to be a traditional theft - a co-worker could simply grab my key from the desk, plug it in, quickly authenticate and put it back. That takes like 10 seconds. IMO this is a worse situation than passwords if you have any kind of password policy.
Honestly I don't like the MFA aspect of the WebAuthn spec at all.
As a security conscious user, I want it to be my decision to additionally protect my credential with a PIN if the service doesn't already enforce this. This is on the spec and on the hardware implementors, as they could add this feature into the firmware. (Yubico already requires PIN entry for AppID enumeration, why not have an option to enforce this for every WebAuthn action?)
As a service administrator I want to be able to force my users to use PINs, at least if they want to go passwordless. This is on the integrators who should support many more options related to WebAuthn verification. Attestation and User Verification at least.
Most helpful comment
technical-details
There should be an option in the settings to make the PIN required.