Webauthn's userVerification:preferred and its Pitfalls

Webauthn is a beauty. A relatively easy to implement way to allow users a secure 2-Factor experience. (easy enough that I could re-create my Webauthn Sandbox after losing it in my migration, FUN!

Well, sarcasm aside, there are a few things I dont like with it, and one of them is the default state of the userVerification Flag.

For anyone who isnt all-aware in Webauthn and stuff: more modern Fido2 devices are generally capable of a feature called userVerification, in other words unlike the relatively simple U2F devices, which only verify that A user is present (e.g. by using a little button or a touchable area which has to be interacted with in the real world) to make sure that malware cant just trigger a connected U2F device and go ham on the accounts it found, user Verification goes another step by actually verifying (hence the name) whether you are an allowed user of this device.

This allows for fun stuff like passwordless logins, as the webauthn can singlehandedly handle 2 factors, one being obviously possession, aka the device, and the other being either usually knowledge (aka a "PIN" which by standards is in fact also capable of being a password or passphrase, but marketing can't really use "password" when "passwordless" is thrown around, lol) or more rarely biometrics like your fingerprint.

Webauthn allows for 3 states of UV:

basically tell the device not to use UV, it still can, if it really wants to, but generally most devices wont.
basically what it says. no UV equals YOU SHALL NOT PASS, while dumb clients not capable of UV can try to push an auth through without UV, required usually means that clients deny devices incapable of UV (like classic U2F sticks) or if a device can do UV but hasnt set it up, helps the user in setting it up.
also a big hint that the server will be making sure that UV is actually used.
the sad default state of UV when the parameter is not used. basically it means that if an authenticator is
1) capable of UV
2) has UV set up
it will use UV, otherwise it wont. it can be used for some hybrid approaches where devices with UV can use it but U2F devices wont explicitly be blocked.

The Problem

as a server doesnt really have psychic powers it cannot predict whether any given device is capable of doing UV so in case preferred is used I doubt that many servers actually verify whether UV is actually used.

This leads to a potential security issue where if the key can be used to bypass passwords or be used in other ways alone without the server actually verifying that UV is used (potentially this can even happen in required, but ideally most libraries are aware of a required request so this wouldnt happen as often), an attacker with the key in hand could use any computer he wants, go to the log in, and swap out the "required" for a "discouraged", and the device will let him through with the push of a button and no UV. This would obviously suck

The Solution

(or at least one of the possibilities)

an Idea I had for a while was to keep track of each credential going around and have an internal UV flag which starts being false, (or 0 or whatever indicating that it isnt used UV in the past) and if any of those EVER spawn a request with UV (of which a flag exists to let the server know), set that internal UV flag to true (or 1 or whatever, you get the idea) and in the future, if a credential with an internal true UV flag is logging in again, turn on the server-side UV validation, this a thief cannot just spawn a discouraged UV prompt and abuse it.


NEVER trust user data

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.