Description
The Problem
- Adding a FIDO2 hardware key effectively / implicitly enables 2FA, but without providing a backup mechanism as with TOTP 2FA. This is potentially dangerous.
- It can be argued that webauthn is supposed to be passwordless auth, enabling 2FA should be a separate choice, and that mandatory TOTP 2FA is reducing security instead of increasing it due to phishing/MITM risk.
- The security settings page misleadingly implies 2FA is not enabled, while it effectively is:
Possbile Solutions
(1) The Very Simple Fix
Revert #11573, but otherwise leave the auth conditions as they are. Fixes the UI inconsistency and the no-backup code situation, implements github's authentication logic, but does not enable passwordless login and makes phishable credentials mandatory.
(2) The Somewhat Simple Fix
- Refactor the web UI: hardware key UI is moved to into the 2FA UI panel, so it's clear that they are not for passwordless auth.
- Require either >=2 fido keys, or generate backup keys, when registering the first fido key. The login flow might also need changes to accept backup codes when no TOTP is registered.
This mostly keeps the current auth logic, except for requiring a backup second factor to be set up:
username && pw && (totp || fidokey1 || fidokey2 || backupcodes)
This auth logic does not require phishable credentials.
(3) The Correct Solution
The most correct way imho would be to implement the auth logic that is outlined below as Nextcloud's implementation.
Effectively the needed changes would be:
- allow registering hardware keys as primary or secondary factor
- migrate existing hardware keys to secondary factor keys
- change auth logic of primary factor keys to actually be replacements for password auth
This would result in the following auth logic:
username && (pw || fidokey1 || fidokey2) && (totp || fidokey3 || backupcodes)
Of course not all of those credentials need to be used, all but one from each block could be unavailable/unknown. This option has the benefit to get along without mandatory phishable credentials (password, TOTP), as well as enabling passwordless auth.
Context
Gitea's current (as of 1.18.0+dev-558-g94d6d93cc, 94d6d93) authentication behaviour is as follows:
context | auth requirements |
---|---|
default | username && pw |
TOTP 2FA enabled | username && pw && (totp || backupkeys) |
(multiple) fido2 keys registered | username && pw && (fidokey1 || fidokey2) |
TOTP 2FA enabled & fido2 keys registered | username && pw && (fidokey1 || fidokey2 || totp || backupcodes) |
For reference some other implementations of FIDO2:
implementation | context | auth requirements |
---|---|---|
github, mastodon | default | username && pw && emailed-token |
TOTP 2FA enabled | username && pw && (totp || backupkeys) |
|
(multiple) fido2 keys registered | case not allowed, must enable 2FA | |
TOTP 2FA enabled & fido2 keys registered | username && pw && (fidokey1 || fidokey2 || totp || backupcodes) |
|
nextcloud | default | username && pw |
TOTP 2FA enabled | username && pw && (totp || backupkeys) |
|
(multiple) fido2 keys registered | username && (pw || fidokey1 || fidokey2) |
|
TOTP 2FA enabled & fido2 keys registered | username && (pw || fidokey1 || fidokey2) && (totp || backupcodes) |
As you can see, there is no clear correct de-facto implementation, I have yet to check fido2/webauthn spec if there is a correct approved way of implementing things. However there is a strong preference in the wider community on how to do things correctly with security and usability in mind:
- on mastodon: Cannot add WebAuthn security keys without adding TOTP first mastodon/mastodon#16693
- earlier on gitea: Allow U2F 2FA when TOTP is disabled #5410
- on gitlab: https://gitlab.com/gitlab-org/gitlab-foss/-/issues/48918