mirror of
https://github.com/dani-garcia/vaultwarden.git
synced 2026-07-17 01:12:27 -05:00
[bug]WebAuth Doesn't Work for testing images #5995
Reference in New Issue
Block a user
Delete Branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Originally created by @IamTaoChen on GitHub (Aug 9, 2025).
Prerequisites
Vaultwarden Support String
Your environment (Generated via diagnostics page)
Config & Details (Generated via diagnostics page)
Show Config & Details
Config:
Vaultwarden Build Version
testing
Deployment method
Official Container Image
Custom deployment method
No response
Reverse Proxy
nginx
Host/Server Operating System
Linux
Operating System Version
Mac
Clients
Browser Extension
Client Version
No response
Steps To Reproduce
SSO_ENABLED = falseand use master password to loginExpected Result
should login
Actual Result
no action after webauth
Logs
Screenshots or Videos
No response
Additional Context
No response
@IamTaoChen commented on GitHub (Aug 9, 2025):
It cannot downgrade to
lastest@BlackDex commented on GitHub (Aug 9, 2025):
You need to either remove 2fa, use a different 2fa type, or restore the record from a backup.
I'm not seeing a failed attempt using webauthn in de first log. I only see duo there. So, not sure what you tried there.
@Blacks-Army commented on GitHub (Aug 9, 2025):
I have the same Error, but only if I use the WebAuthn Passkey from my Bitwarden Account in Bitwarden. If I use my YubiKey it works.
Edit: It also happens with the yubikey here the log:
@Blacks-Army commented on GitHub (Aug 9, 2025):
Maybe my issue is related to PR #5934?
@BlackDex commented on GitHub (Aug 9, 2025):
I see strange stuff regarding non-utf-8 characters in your logs. Those shouldn't be happening at all. That might also break the WebauthN data sent to the server.
Not sure what is in between the browser and the Vaultwarden instance, but it looks like it is adjusting your WebAuthN response to the server.
@Blacks-Army commented on GitHub (Aug 9, 2025):
I am using Traefik, but this also did not happened before. Traefik only sets Headers and Rate Limits.
Edit: And I am not setting a Header named cookie
@BlackDex commented on GitHub (Aug 9, 2025):
I'm unable to reproduce this on my side.
I used the current stable version to create the 2FA tokens, and i used both SoftU2F and my YubiKey5c. Then compiled the main branch, and logged in just fine.
Be sure you have HTTPS working with a valid certificate. Check
/admin/diagnosticsto see if there are issues.@IamTaoChen i would suggest to make the admin interface available so that you can also check the diagnostics page. It provides us useful information which otherwise makes it almost impossible for us to help in a useful way.
@Blacks-Army, In your case it looks like it has something to do with a backup key. Not sure which key you are using right now, is that the key used during the creation, or are you now using the backup key to verify.
I noticed something similar in Proxmox regarding this message. But, i do not have the means to test this my self, as i do not have two YubiKey's.
@BlackDex commented on GitHub (Aug 9, 2025):
As a reference to where i found it at Proxmox: https://git.proxmox.com/?p=proxmox.git;a=commit;h=e4d5cce8ec7b97353b4c922424bf1bc4dcede420
@zUnixorn, maybe you have an idea regarding this?
@BlackDex commented on GitHub (Aug 9, 2025):
I't might be as easy as allowing
allow_backup_eligible_upgradebut I'm not sure.@BlackDex commented on GitHub (Aug 9, 2025):
Also, looking at the code and description from YubiKey it self. It might be you registered the spare key (which you might be using right now) after you verified the main key in Vaultwarden. If that is the case, then i think this error is legit, and increases security of Vaultwarden. I think the previous implementation just didn't bothered looking at it, and that is why you were able to use it and login.
@Blacks-Army commented on GitHub (Aug 9, 2025):
In the Admin Diagnostics I only get this
API calls:
Header: 'x-xss-protection' does not contain '0'
2FA Connector calls:
Header: 'x-xss-protection' does not contain '0'
Header: 'x-frame-options' is present while it should not
@Blacks-Army commented on GitHub (Aug 9, 2025):
Well in Vaultwarden I have multiple Keys. Why does it matter which I use I do not understand tbh.
PassKey - IOS Keychain
YubiKey 5C NFC (Main)
Bitwarden - in the vault itself
@IamTaoChen commented on GitHub (Aug 9, 2025):
Sorry, it’s evening here in China and I’ve had a few beers. I’ll run the tests and add more logs tomorrow.
@IamTaoChen commented on GitHub (Aug 9, 2025):
I have some update about Client Actions (Mac Chrome Extension & Desktop App)
I am not certain whether these actions are directly related to the this issue being discussed.
Sorry, this comment is using the latest image not testing(I forgot to mention it before)
@BlackDex commented on GitHub (Aug 9, 2025):
@Blacks-Army, i would suggest to fix those items, as they might cause some weird issues with some clients.
I tried on a macOS device, and I'm able to add a key, but afterwards I'm unable to login with it.
Using my YubiKey5c on the mac works fine though.
@BlackDex commented on GitHub (Aug 9, 2025):
Maybe @yaleman or @Firstyear have some clue regarding this? (Sorry for tagging)
@BlackDex commented on GitHub (Aug 9, 2025):
@IamTaoChen, if you are not using
:latest, then it can't have anything to do with the latest webauthn-rs version, as that currently is only in the:testingtagged images.I wouldn't be surprised if Apple doesn't fully adhere to the standards which might cause issues.
@Blacks-Army commented on GitHub (Aug 9, 2025):
Removing the Headers did not fix anything.
However I noticed that this only happens on Software saved Passkeys like a Passkey saved in the Apple Keychain or in Bitwarden itself.
It works with YubiKey as a Passkey and Yubico OTP.
@IamTaoChen commented on GitHub (Aug 9, 2025):
I update the diagnostics page
@IamTaoChen commented on GitHub (Aug 9, 2025):
Testing Image
Login with master password
2FA by PassKey
2FA by Authebticater APP
Wroks.
@IamTaoChen commented on GitHub (Aug 9, 2025):
@BlackDex Hi, I have noticed that the diagnostics page(Support String) displays certain OIDC information that is not concealed.(not about this issue, but maybe important)
@IamTaoChen commented on GitHub (Aug 9, 2025):
I'll revcover my DB. if any other information need, please let me know.
@BlackDex commented on GitHub (Aug 9, 2025):
@Timshel
@stefan0xC commented on GitHub (Aug 9, 2025):
I think we should be masking (at least)
sso_client_idandsso_authorityherea133d4e90c/src/config.rs (L268-L272)@IamTaoChen commented on GitHub (Aug 9, 2025):
and
sso_callback_pathwhich contains the domain of vaultwarden@Blacks-Army commented on GitHub (Aug 9, 2025):
You mean the secret right?
@stefan0xC commented on GitHub (Aug 9, 2025):
Nope. That already is of type
Passso it's hidden already. I've updated my PR #6153 to also mask those three options.@Timshel commented on GitHub (Aug 9, 2025):
When debugging an issue the
sso_authoritycan be useful, but it can be sensitive too.The
sso_client_idwill almost certainly never be useful.@zUnixorn commented on GitHub (Aug 9, 2025):
Looking at the code (here), this seems to be the problem, I am not sure what this means though.
The value of
allow_backup_eligible_upgradeseems to be a difference between start_securitykey_authentication() and start_passkey_authentication().start_passkey_authentication()allowsallow_backup_eligible_upgradewhilestart_securitykey_authenticationdisallowsallow_backup_eligible_upgrade.Unfortunately I don't know what security implications this has. Originally
start_passkey_authentication()was used but it required modifying the JSON, nowstart_securitykey_authentication()is used since it produces the same JSON webauthn request as before the crate update, but as it seems, it doesn't allowallow_backup_eligible_upgrade.In the CredentialV3 this wasn't present, in the migration, a value of
falseis assumed forbackup_eligible.I think allowing
allow_backup_eligible_upgradeusing the underlying webauthn_core_rs crate or usingstart_passkey_authentication()as before, could fix this.Since you already pinged two Maintainers of webauthn-rs, maybe they know what security implication
allow_backup_eligible_upgradehas and why this is allowed forstart_passkey_authentication()but notstart_securitykey_authentication()The docs mention the following regarding the *_security_key() methods:
Maybe this is the reason that security keys work but passkeys don't always?
Contrary to the initial suggestion, using
start_passkey_authentication()may be more compatible with the original implementation with webauthn-rs 0.3@zUnixorn commented on GitHub (Aug 9, 2025):
I reverted to using the original start_passkey_authentication() approach in this branch: https://github.com/zUnixorn/vaultwarden/tree/use_passkey_methods_webauthn_rs
I couldn't reproduce this issue on my end and cannot test this, but you could try if the version in my branch exhibits the same behavior or if it actually fixes the problem.
@Firstyear commented on GitHub (Aug 10, 2025):
The difference is that it allows a key that was previously hardware bound to a single device, to now be transient to many devices. As an RP, this changes the security assumptions of the device, since what you thought was single device, now has moved.
In general for the vaultwarden use case, you probably want "securitykey" options here, because that treats the device as a single factor, where as passkeys treat the device as self-contained multifactor and will force user verification.
@Blacks-Army commented on GitHub (Aug 10, 2025):
I don't know if I quite understand that, but does that mean we need to use
start_passkey_authentication()for soft tokens (passkeys in password managers) to work?@BlackDex commented on GitHub (Aug 10, 2025):
I'm not sure what v0.3.2 was using as it's base verification policy, which we should try to not change i think.
But Bitwarden did renamed the MFA option from WebauthN/FIDO to Passkeys. While I'm of course for more security, it might make it more difficult for users to use the same WebauthN on both there iOS device and macOS. Or maybe an Android device which was transferred, of that modifies something maybe, or possibly at all.
I might check what the different outcome will be between the two options.
@Blacks-Army commented on GitHub (Aug 10, 2025):
Is there an image available? Or do I need to build it myself? If so I don't know how...
@zUnixorn commented on GitHub (Aug 10, 2025):
Currently there is no image available, but I can build one later so it's easier to test. I will comment it here, when i've come around to make one available.
@BlackDex commented on GitHub (Aug 10, 2025):
I tried with the patch form @zUnixorn, but that doesn't solve the Apple macOS/iOS issue for me.
Either it's not fully supported by webauthn-rs, or it's not using standards.
Unfortunately the test/demo application isn't working of webauthn-rs, which prevents me, and others from seeing which data is transfered/used to try and authenticate. This might help the developers of webauthn-rs to fix issues or maybe supply some details regarding issues with some of these devices.
@Blacks-Army commented on GitHub (Aug 10, 2025):
Kanidm uses also webauthn-rs 0.5.2 and there it does work
38b54969d1/Cargo.toml (L305C1-L305C69)@Blacks-Army commented on GitHub (Aug 10, 2025):
I am just seeing this part maybe we need this dependency?
38b54969d1/Cargo.toml (L302)@BlackDex commented on GitHub (Aug 10, 2025):
@Blacks-Army, that seems to be the client-side of the code, not server-side, and thus not something useful.
I do think i see some strange things though. Currently debugging to see what the difference are.
@BlackDex commented on GitHub (Aug 10, 2025):
Yes, I have found a bug which prevents almost every device except for some hardware keys to continue.
Here:
e35c6f8705/src/api/core/two_factor/webauthn.rs (L437)There is a check if the credential id's match, but, it also checks if there is an updated needed, but if that part fails, the whole authentication fails. And, if i read the documentation correctly, almost no device uses this feature, and it's also not really needed.
Ill check what happens if i update this. But, that still leaves me a bit undecided if using
securityorpasskeywould be the right way to go. But, since we probably want to have Soft tokens like Apple work cross device, and that needs to allow thebackup_stateto be able to be set totrue, I thinkpasskeysis probably the way to go.@BlackDex commented on GitHub (Aug 10, 2025):
I Found the issue and created a PR to fix this.
@BlackDex commented on GitHub (Aug 10, 2025):
Once https://github.com/dani-garcia/vaultwarden/actions/runs/16864227130 is finished you should be able to test if this fully resolves the issues reported here by using the
:testingtagged images.@IamTaoChen commented on GitHub (Aug 10, 2025):
No, It still doesn't work
@Blacks-Army commented on GitHub (Aug 10, 2025):
For me it is not working... Same Error
@BlackDex commented on GitHub (Aug 10, 2025):
And you both are sure you did a
docker pullordocker compose pullfirst?What is the version running? Does it has the last commit tag currently in our main branch?
Also @Blacks-Army, do you still have those strange header errors? And did you fixed those warnings the diagnostics page reported?
@Blacks-Army commented on GitHub (Aug 10, 2025):
Yes I did and I even checked the Digset
@BlackDex commented on GitHub (Aug 10, 2025):
Also, i think that the issue regarding @IamTaoChen still is because of the backup key is being used in some way. And not the original key used, but I'm not 100% sure regarding that.
Then maybe @zUnixorn could rebase on main, and provide a working image maybe of his security > passkey changes?
That is then the only item i think could be the issue then.
But, at least Bitwarden Passkeys and macOS/iOS Passkeys work again without issues.
@Blacks-Army commented on GitHub (Aug 10, 2025):
For me iOS and Bitwarden Passkeys didn't work... did you maybe add them on a freshly installed instance? I am doing a Upgrade and want to use my already saved passkeys.
@BlackDex commented on GitHub (Aug 10, 2025):
Well they were migrated. But i can of course try that again.
But that will probably be tomorrow.
@zUnixorn commented on GitHub (Aug 11, 2025):
Ok, I rebased and generated the docker images with the
*_passkey_*methods based on alpine or debian:docker pull ghcr.io/zunixorn/vaultwarden:testing-alpinedocker pull ghcr.io/zunixorn/vaultwarden:testingDoes the problem persist with these versions?
@Blacks-Army commented on GitHub (Aug 11, 2025):
Not for me...
@zUnixorn commented on GitHub (Aug 11, 2025):
Now it does not fail with
CredentialBackupElligibilityInconsistentbut instead withCredentialMayNotBeHardwareBoundso switching to the passkey methods did indeed fix that previous error. Since your passkey seems to have thebackup_stateset totrue, but the migration defaults tofalseforbackup_eligible, the webauthn crate doesn't allow you to verify with that passkey.I updated the docker image to migrate the passkeys with
backup_eligibleexplicitly set totrue, I don't know if that's something that should be done, but if this fixes the problem, we at least know where the problem lies.So if you update the image, the
CredentialMayNotBeHardwareBounderror hopefully goes away too.@Blacks-Army commented on GitHub (Aug 11, 2025):
It works now! Thanks!
@zUnixorn commented on GitHub (Aug 11, 2025):
Thank you for testing this! Maybe this fixed @IamTaoChen's problem as well.
Now the question is, if it is desired to always migrate the old passkeys withbackup_eligibleset totrueand using the*_passkey_*methods instead of*_securitykey_*. Since the webauthn 0.3 version didn't even check nor track this, I would think that allowing this wouldn't make this less secure then the v0.3 implementation, but I am not sure if this assumption is actually correct.@BlackDex commented on GitHub (Aug 11, 2025):
I would say, use passkeys, as that is also what Bitwarden calls it these days in the Security Settings of the user.
It would also help implementing the actual passkey login feature i guess, to not have multiple types of webauthn formats.
And, indeed, to stay compatible with the previous versions, i would say switch to
*_passkey_*. If you can create a PR for that, then Ill do some tests my self too, and if ok, ill merge :).@zUnixorn commented on GitHub (Aug 11, 2025):
I will create a PR for that later today.
Should I also change thebackup_eligiblevalue (this field) like I did in my current branch or leave it and only change to the passkey methods?@BlackDex commented on GitHub (Aug 11, 2025):
If I'm correct leaving that off and switch to passkeys should solve it right? Since passkeys has that enabled by default?
@Blacks-Army commented on GitHub (Aug 11, 2025):
No, by default it is
false@zUnixorn commented on GitHub (Aug 11, 2025):
Ok after thinking about it, switching to passkeys should be enough. When I only applied that change, there was still
CredentialMayNotBeHardwareBoundthrown as an error. But after looking through the webauthn-rs code, this shouldn't happen ifupdate_credential()is called, since it should updatebackup_eligiblewhich would preventCredentialMayNotBeHardwareBoundfrom being thrown.@Blacks-Army when you tested the first change that didn't work, did you try to authenticate multiple times or just once? I can't test it myself but I would think that it should only fail the first time but update
backup_eligible. The second time it should work, because the value is set correctly then.@Blacks-Army commented on GitHub (Aug 11, 2025):
I don't know anymore. I would need to test it again
@zUnixorn commented on GitHub (Aug 11, 2025):
Ok, could you try this image again:
docker pull ghcr.io/zunixorn/vaultwarden@sha256:c6a9c574220ad650e7ee321366d3216b47d848651d2d5cb5ebf5ba674f5f4535And then try to authenticate 2 times, the first time should fail but update the stored backup eligibility and the second time should hopefully work then.
@zUnixorn commented on GitHub (Aug 11, 2025):
If that's not the case the Credential doesn't get updated properly and then that should be fixed instead.
@Blacks-Army commented on GitHub (Aug 11, 2025):
Nope it does not work I am getting the same Error Message
@BlackDex commented on GitHub (Aug 11, 2025):
Hmm.. I'm not sure we should set it for all items as you currently do @zUnixorn.
My YubiKey for example has that set to false, which i would like to keep it that way. As that is a physical token and not software.
The
*_passkey_*functions allow that boolean to be true. But, it doesn't force it to be true.Setting everything to true, could cause a security issue i think.
@zUnixorn commented on GitHub (Aug 11, 2025):
Yeah, that's not the correct way. But I think I know what the problem is now.
When
allow_backup_eligible_upgradethebackup_eligibleshould be updated whenupdate_credential()is called. This works when thebackup_stateis stillfalsee.g. the Passkey wasn't backed up. Because in that case the Authentication doesn't throw an error which allowsupdate_credential()to be called and sincebackup_eligibleis now set to the correct value, future authentications even after the key was backed up e.g.backup_stateistrue, will work fine.But if the key was already backed up before the migration,
backup_stateis already true, which fails the Authentication and therefore prevents updating the Credential, which would actually solve the problem.I am not sure if this is intended or a bug, but I am thinking about opening an issue in webauthn-rs since migrating already backed up passkeys seems to be impossible with my current understanding of its implementation.
For Reference:
backup_stateis true whenbackup_eligiblewasn't updated, regardless ofallow_backup_eligible_upgrade's value.backup_eligible, finish_passkey_authentication() must succeed to get the updated AuthenticationResult and use it to update the credential'sbackup_eligiblewith update_credential()@BlackDex commented on GitHub (Aug 11, 2025):
The problem here is, that my Hardware token, a YubiKey5c, has it set to false. You arn't allowed to set
truetofalsefor this flag. Fromfalsetotrueis allowed.Using your latest patched version breaks my YubiKey login, but all the others are working now.
The main problem here is the migration. It migrates all items without knowing the correct values.
The only way i see to fix this, is migrate per credential upon usage, and extract the correct values from the provided V5 layout.
@zUnixorn commented on GitHub (Aug 11, 2025):
I opened https://github.com/kanidm/webauthn-rs/issues/510, maybe I missed something but I am not sure how CredentialV3 is supposed to be migrated to CredentialV5 when the Passkey was backed up previously
@zUnixorn commented on GitHub (Aug 11, 2025):
Yes, that's my understanding as well.
Since the authenticator tells us what it expects to be the correct values, they could be set before authenticating to the correct ones, which would make this work correctly.
Normally this would be done automatically here, but because of the the "invalid state", it does not.
Unfortunately, manually setting the
backup_eligibleto the one provided by the authenticator upon first authentication would be quite hard since there would be some parsing to do without the help of the webauthn-rs crate. So this should ideally be possible to do in webauthn-rs itself for the purpose of migrating to the more extensive CredentialV5.@Blacks-Army commented on GitHub (Aug 11, 2025):
Could I use your image @zUnixorn then migrate the soft passkeys and then update to the latest vaultwarden/server image? That should work right?
@BlackDex commented on GitHub (Aug 11, 2025):
You could also manually modify the json. But keep in mind, hardware tokens will break with that image
@Blacks-Army commented on GitHub (Aug 11, 2025):
No I mean I would migrate the soft passkeys with the image where it works (and don't touch the security keys) and then change it to the latest of this repo, that should work or not?
@BlackDex commented on GitHub (Aug 11, 2025):
And how do you prevent the hardware keys from being touched then? All are migrated in one go.
@Blacks-Army commented on GitHub (Aug 11, 2025):
Ahh okay, didn't know that.
@Firstyear commented on GitHub (Aug 13, 2025):
Both of these are kind of symptomatic of the issue, which was the webauthn wg and fido completely rewriting the rules underneath everyone. We went from a standard that was "hardware bound, touch only" to now having software authenticators that lie about their capabilities, authenticators that move between places, pretty much forced PIV/biometrics on many authenticators and more. There is so much confusion about this topic, and even just to highlight how confusing it is, there are 5 different definitions of what a passkey is!!!
And that's a big problem, because we wrote webauthn-rs at a time when we started with the first (hardware only single factors, maybe you had a PIN if you were hardcore). And then we've had to adapt and change as we go, trying to understand what the threats/risks were and wrap up them nicely so that people can have nice safe interfaces that "just work". We've always tried to model the library around "user experiences and workflows" and we've been forced to change those flows as webauthn has become messier and more confusing, and even undermined their own original workflows.
So at the time when we wrote the v3 -> v5 credential layout migration, there were no roaming authenticators, so we made an assumption of "well, nothing was backup eligible, default to false". But it's now what 3 or so years since then, and now when you do that migration that assumption is no longer true. There are so many roaming authenticators out there (even vaultwarden!) that we can't make that assumption.
Anyway, I made a PR to hopefully resolve this for you which assumes every authenticator was backup eligible by default. I do not believe this undermines anything for you. But I will caution and warn you that the issue now with how passkeys work is that they require userVerification, they are no longer just a touch and move on. You must enter a PIN or some other form of UV. This means older u2f style keys will fail to work in future where you expect just to touch and proceed.
@BlackDex commented on GitHub (Aug 16, 2025):
I think i have tackled this issue now.
With some voodoo done during the response and verification Software/Passkeys should now work without issues after a migration. If you already migrated before, this should still fix those issues, as nothing is changed on how the migration converted the v3 to the v5 credentials.
@Blacks-Army commented on GitHub (Aug 18, 2025):
I have just reregistered all PassKeys it works now