keepassxreboot / keepassxc

KeePassXC is a cross-platform community-driven port of the Windows application “Keepass Password Safe”.
https://keepassxc.org/
Other
20.97k stars 1.45k forks source link

[Passkeys] When UV is required, KeePassXC must request user verification or not handle the request #10406

Open timcappalli opened 6 months ago

timcappalli commented 6 months ago

Overview

In WebAuthn, there are 3 modes for user verification that an RP can request: required, preferred, and discouraged.

https://www.w3.org/TR/webauthn-2/#enum-userVerificationRequirement

When required, the authenticator must perform user verification (PIN, biometric, or some other unlock mechanism). If this is not possible, the authenticator should not handle the request.

When preferred, the authenticator should try its best to perform user verification (e.g. if a biometric sensor is available or a PIN is set), but may choose not to in the interest of a better user experience. In this case, the request can succeed, but UV must be returned as false / 0.

When discouraged, the authenticator should not perform user verification and return UV = false/0

Steps to Reproduce

[!NOTE]
These apply to both creation and authentication flows.

Scenario 1 (UV=Required)

  1. Go to WebAuthn.io and select UV required in the configuration, start the flow
  2. KeepPassXC asks you to confirm
  3. WebAuthn promise resolved, request successful (UV=1 in authData)

Scenario 2 (UV=Preferred)

  1. Go to WebAuthn.io and select UV required in the configuration, start the flow
  2. KeepPassXC asks you to confirm
  3. WebAuthn promise resolved, request successful (UV: true/1 in authData)

Expected Behavior

Scenario 1 (UV=Required)

  1. Go to WebAuthn.io and select UV required in the configuration, start the flow 2a. If KeePassXC does not have the capability to do UV, the request should be aborted 2b. If KeePassXC has the capability to do UV, request UV, and if successful, continue 3a. n/a 3b. WebAuthn promise resolved, request successful (UV: true/1 in authData)

Scenario 2 (UV=Preferred)

  1. Go to WebAuthn.io and select UV preferred in the configuration, start the flow 2a. If KeePassXC does not have the capability to do UV or the KeePass believe the UX will be poor based on available context (e.g. bio sensor available), continue the request 2b. If KeePassXC has the capability to do UV and KeePassXC believes it is a good UX for the user based on context (e.g. bio sensor available, PIN set, etc), request UV, and if successful, continue 3a. WebAuthn promise resolved, request successful (UV: false/0 in authData) 3b. WebAuthn promise resolved, request successful (UV: true/1 in authData)

Actual Behavior

This implementation is not spec compliant and has the potential to be blocked by relying parties.

Context

KeePassXC - Version 2.7.7 Revision: 68e2dd8

Qt 5.15.11 Debugging mode is disabled.

Operating system: macOS 14.4 CPU architecture: arm64 Kernel: darwin 23.4.0

Enabled extensions:

Cryptographic libraries:

timcappalli commented 6 months ago

This should be tagged as a security issue as well.

droidmonkey commented 6 months ago

I'm confused why an unlocked database and the user confirm a prompt does not constitute verification. If the user's database is unlocked, showing a prompt to "further unlock/prove access" is rather irrelevant.

Users that desire more security in this aspect can either manually lock their database or set a short timeout for locking. That would require them to use quickunlock (pin/bio) or their full credentials prior to using passkeys.

timcappalli commented 6 months ago

Confirming a prompt would be User Presence, which is always required. For both UP and UV, WebAuthn requires that the gesture occur during the ceremony itself. A vault could have been unlocked 8 hours ago and the user stepped away after 1 hour.

If the user's database is unlocked, showing a prompt to "further unlock/prove access" is rather irrelevant.

Users are quite used to using their biometric or PIN to authorize a sign in or transaction. This is a standard pattern across the ecosystem.

droidmonkey commented 6 months ago

A vault could have been unlocked 8 hours ago and the user stepped away after 1 hour.

Yet their database is still unlocked. Which means (since you are assuming an attacker scenario here) I can simply copy your passkey data (and everything else) from your database and do an auth on my own terms. After all, this is entirely client side reported compliance, and the RP has absolutely no way to verify/validate this ever happened.

What I am saying is we have a mechanism to do user verification that actually matters, and that involves locking your database when you aren't using it.

This implementation is not spec compliant and has the potential to be blocked by relying parties.

How can relying parties even know? It's just a self reported boolean value.

timcappalli commented 6 months ago

What I am saying is we have a mechanism to do user verification that actually matters, and that involves locking your database when you aren't using it.

Then you should require its use when passkeys are enabled

How can relying parties even know? It's just a self reported boolean value.

You are identifying yourself to relying parties, and you have a passkey provider that is known to not be spec compliant.

varjolintu commented 6 months ago

Users are quite used to using their biometric or PIN to authorize a sign in or transaction. This is a standard pattern across the ecosystem.

Do other desktop password managers do this? As far as I know, they are also just confirming these actions with a simple popup.

timcappalli commented 6 months ago

Do other desktop password managers do this? As far as I know, they are also just confirming these actions with a simple popup.

All native passkey providers behave as defined in the specification w.r.t. to UP and UV, and a majority of third party providers are responding truthfully about UV.

varjolintu commented 6 months ago

Do other desktop password managers do this? As far as I know, they are also just confirming these actions with a simple popup.

All native passkey providers behave as defined in the specification w.r.t. to UP and UV, and a majority of third party providers are responding truthfully about UV.

This includes all password managers that are using passkeys via their own browser extension, including Dashlane, Bitwarden etc.?

droidmonkey commented 6 months ago

You are identifying yourself to relying parties, and you have a passkey provider that is known to not be spec compliant.

What stops us, or anyone else, from simply changing the self reported, self generated AAGUID? There is no passkey certification process, no signed stamp of approval from on high. RP's blocking arbitrary AAGUIDs doesn't seem like a thing that's going to happen or that can even make a difference. Get blocked change the GUID. Maybe even present a random one every time.

At the end of the day, this is all client side reported information with absolutely zero validation capability by the RP. So, to me, this is a user choice. Do I use keepassxc and accept their security model (lock your database dangit) or use another authenticator.

timcappalli commented 6 months ago

What stops us, or anyone else, from simply changing the self reported, self generated AAGUID?

AAGUIDs for synced passkey providers are currently only designed to be used for UX in RP account management screens, but nothing is stopping an RP from using it for other restrictions.

There is no passkey certification process

This is currently being defined and is almost complete.

no signed stamp of approval from on high

see above. Once certification and attestation goes live, there will be a minimum functional and security bar for providers.

RP's blocking arbitrary AAGUIDs doesn't seem like a thing that's going to happen or that can even make a difference

It does happen and will continue to happen because of non-spec compliant implementations and authenticators with poor security posture.

So, to me, this is a user choice.

Sure, I guess it is always a user choice. But as technologists, its important to build products that help users be secure by default and which play nicely in a standards-based ecosystem.

At the end of the day, it is your product. You do you. I've taken a lot of my personal time to point out some things that should be addressed, things that are huge sticking points for the ecosystem over this 3+ year journey.

droidmonkey commented 6 months ago

I want to clarify myself, I am definitely not saying user verification isn't important nor do we not want to support it. We technically do support it with a locked database. I am playing devil's advocate on how the spec is requiring things to happen and there can technically be no way to know that besides this conversation or a very curious user who knows the spec.

I am for an option (perhaps enabled by default) that requires entering the database credentials again, even if the database is unlocked.

Good to hear there will be a cert process, I hope it is not too expensive 😄 I already pay $350 a year for the pleasure of signing my windows builds.

droidmonkey commented 6 months ago

@timcappalli also thank you for helping us here, its been a journey so far with this implementation.

timcappalli commented 6 months ago

I am for an option (perhaps enabled by default) that requires entering the database credentials again, even if the database is unlocked.

Many authenticators use a device PIN or biometric gesture instead. Since your architecture requires the native app, this should be fairly easy to do on Windows and Mac. I wouldn't recommend making the user enter their database password every time.

josephcsible commented 6 months ago

If we do add support for user verification, there should be a setting to disable it. This is a misfeature of the spec and we should be willing to ignore it, just like autocomplete="off" for password fields.

josephcsible commented 6 months ago

Once certification and attestation goes live, there will be a minimum functional and security bar for providers.

Wouldn't any such thing be incompatible with any FOSS implementation of passkeys?

droidmonkey commented 6 months ago

We have pin-based quick unlock in the pipeline, so even Linux users without biometrics and an OS-backed crypto store can be covered by some form of "quick" user verification.

Regarding the potential of being blocked, whether by financial relationships or because of spec noncompliance, I would very much prefer the spec require RP's to declare they have blocked a specific provider in the error message presented to the end user.

I have a sneaky suspicion that some of our failures with various RP's is because they are only accepting certain authenticator GUIDs. This is even though it's not allowed per the spec at this time. I'm a realist and know that a whole lot of parties will not actually comply with the spec in whole, especially if they are closed source.

The lack of defined and required error messages allows for sneaky and undesirable behavior disguised as "unknown error occurred".

josephcsible commented 6 months ago

@matthewmummert5 Let me clarify: I'm not saying that it's impossible for a FOSS project to sign an attestation somehow. I'm saying that if replying parties start setting a "minimum functional and security bar", there will be no way they'd ever accept an attestation belonging to any FOSS authenticator, since even if the official build did meet the bar, someone could be using a modified build that doesn't meet it and still get the same attestation. And any technical measures to prevent this would result in the authenticator no longer being FOSS.

I also share all of the same worries about relying parties blocking authenticators that you do. IMO, attestation has no legitimate uses and its only purposes are anticompetitive behavior and taking control away from the user.

dhs-aws commented 6 months ago

The FIDO spec does not take a position on whether an authenticator is acceptable to an RP or not. RPs are free to make risk based decisions about the suitability of an authenticator. This is outlined in the MDS specifications.

RPs can and will make decisions about authenticator suitability based on the available evidence - or lack thereof. This is not an issue with KeePassXC, rather a business decision to be made by RPs.

-dhs

-- Sent from my pocket TRS-80

On Mar 14, 2024, at 7:30 PM, Jonathan White @.***> wrote:



We have pin-based quick unlock in the pipeline, so even Linux users without biometrics and an OS-backed crypto store can be covered by some form of "quick" user verification.

Regarding the potential of being blocked, whether by financial relationships or because of spec noncompliance, I would very much prefer the spec require RP's to declare they have blocked a specific provider in the error message presented to the end user.

I have a sneaky suspicion that some of our failures with various RP's is because they are only accepting certain authenticator GUIDs. This is even though it's not allowed per the spec at this time. I'm a realist and know that a whole lot of parties will not actually comply with the spec in whole, especially if they are closed source.

The lack of defined and required error messages allows for sneaky and undesirable behavior disguised as "unknown error occurred".

— Reply to this email directly, view it on GitHubhttps://github.com/keepassxreboot/keepassxc/issues/10406#issuecomment-1998833257, or unsubscribehttps://github.com/notifications/unsubscribe-auth/AIA3J2PVGSOUAKPMPAUQQ4LYYJMLJAVCNFSM6AAAAABESUYSP6VHI2DSMVQWIX3LMV43OSLTON2WKQ3PNVWWK3TUHMYTSOJYHAZTGMRVG4. You are receiving this because you are subscribed to this thread.Message ID: @.***>

droidmonkey commented 6 months ago

I absolutely concur with risk-based decision making, especially in a zero-trust context. Personally, if I was running an enterprise I would only trust an HSM token (ie, hardware bound certificates) as a passkey authenticator for business sensitive applications. However, the only way to make those risk based decisions is to also have trust in the authenticator using cryptographic proofs of validity and being untampered (attestation). Should that be pushed onto ALL authenticators, absolutely not. You only push attestation onto ones that would be relevant to an enterprise or highly secure context. General users accessing various low-tier websites don't need that level of scrutiny to their authentication experience. The website itself, I would argue, is the weak point in the security chain, not the authentication mechanism.

dhs-aws commented 6 months ago

I don't disagree with many of your points, but I do want to tackle one in particular: do consumers need attestable credentials? Yes.

Attestable credentials aren't needed for every use case - slashdot and my bank require different levels of authentication assurance - but there are clear use cases that benefit from attestation. I suspect we'll see it required by regulation in some geo-regions.

Passkeys are highly phishing resistant, but if access to them is gated by weak mechanisms, or they are exportable to cleartext, then we can expect social engineering attacks to quickly follow. Here's a recent example of social engineering in the password manager space: https://blog.lastpass.com/posts/2024/02/warning-fraudulent-app-impersonating-lastpass-currently-available-in-apple-app-store.

On the subject of death... This is something I've been working on. There are already mechanisms in place at some providers to handle death or disablement, but we still lack consent-driven mechanisms that are broadly accepted by providers. I'll have more to share at IIW (https://internetidentityworkshop.com/) and Identiverse (https://identiverse.com/idv24/session/2089655/).

josephcsible commented 6 months ago

@dhs-aws How could attestation ever benefit consumers, even for high-security things like banks? If consumers want higher-security authenticators like hardware-backed tokens, they're free to use them even without attestation. All it does is take away choice. (I don't find the argument about being social engineered into downloading malware convincing, because if you do that, it could just hijack your session after you authenticate.)

varjolintu commented 6 months ago

It's also possible to use a passkey only for 2FA. Should those keys also use attestation if that would be a requirement by the RP?

dhs-aws commented 6 months ago

I see a lot of misinformation and incorrect guesses about the intentions of various parties in the recent threads. If it would be helpful, I'm willing to have a call with interested parties to try and answer some of the questions that have been raised to ensure we have a common technical understanding of FIDO/WebAuthn.

danShumway commented 6 months ago

I'm willing to have a call with interested parties to try and answer some of the questions

@dhs-aws Could this be handled in a more public setting? I'm not convinced that it's useful to correct misconceptions or talk about motivations in private. Many of the attitudes I'm seeing expressed here are very commonplace perceptions of the passkey ecosystem and of the goals of companies involved in the FIDO Alliance; if these attitudes are wrong, they will still keep popping up if there's nothing easy to find online to refer to that corrects them and clarifies what the intentions of all the relevant parties actually are.

I don't think that handling corrections over social media or individual calls is going to change general perception of these issues. And people who look at these recent threads and come away with the (justified or not) impression that attestation is a danger to Open Source providers in general -- are not likely to be swayed by knowing that a conversation happened somewhere.

That's not to say that individual conversations are bad, but if there is some kind of meeting in which the more experienced devs/parties here reach a common ground about what specifically was meant in comments like https://github.com/keepassxreboot/keepassxc/issues/10406#issuecomment-1994313373 -- can that call please be recorded or at least documented and posted publicly, and then linked to within this thread? I at the very least don't necessarily feel qualified to participate in a conversation like that, but I would love to know the technical information that gets shared.

If there's misinformation, people should be able to find what the correct information is. Ideally they should be able to find it someplace more official than a 3rd-party Github repo, but at least they should see a reference to it in the same place where they're reading these comments. Otherwise, they'll walk away remembering the arguments that were made here publicly, and it won't matter for their perception of passkeys what was said in a private call. The general fear that people have about attestation and the danger of allowing services to arbitrarily block Open Source providers is not something that can be solved privately or individually.

dhs-aws commented 6 months ago

The low bandwidth nature of github doesn't facilitate effective discussions for these kinds of topics, based on my experience.

danShumway commented 6 months ago

That makes sense. Would it be possible for whatever discussion happens to be recorded or summarized after the fact?

My concern is that no one reading this thread is going to come away with anything other than the comments made here. If there's misinformation that gets corrected elsewhere and it's never linked back here, then it won't be corrected for the vast majority of readers. Doesn't need to happen through Github, but if there are facts people are getting wrong, there should be some way to learn what the mistakes are. "There's a lot of misinformation" isn't helpful on its own to future readers or to anyone who's not privy to the conversations that happen elsewhere. They'll read what people have said here, take away what they can take away, and if there's no other resource linked to from here or no followup that they can see, then that will shape what their perception is of the passkey ecosystem.

danShumway commented 6 months ago

Was there any followup on this? Did any conversations happen?

varjolintu commented 6 months ago

If anyone's interested, I found this list that now also mentions KeePassXC: https://passkeys.dev/docs/reference/known-issues/

johnmaguire commented 6 months ago

Regarding the potential of being blocked, whether by financial relationships or because of spec noncompliance, I would very much prefer the spec require RP's to declare they have blocked a specific provider in the error message presented to the end user.

It seems to me that there is a certain irony to this request, given that RPs could always ignore this part of the spec - just as KeePassXC chooses to ignore parts of the spec related to UV.

danShumway commented 6 months ago

given that RPs could always ignore this part of the spec

Of course, but bad behavior probably shouldn't be condoned or sanctioned by the spec. Under the current situation, an RP can give totally unhelpful errors and then go brag that they're spec-compliant.

If we're OK with spec deviations, sure, it's anybody's game. But if we're aiming for compliance, even to the point of getting certification involved... we should have tools to make this whole process smoother. At the very least, having this kind of better messaging be part of the spec as an outright requirement makes it much more likely that reference implementations and libraries for RPs will implement the correct behavior, which would likely have a positive impact on how a lot of smaller RPs operate.

And of course there's no guarantee that the reason a provider is blocked is because of spec-compliance issues. Even in these early days, I've seen confusion from users about why certain providers don't work with certain sites, where the issue basically comes down to -- it's early days, and the website is using user-agent sniffing and not allowing your browser and throwing up an error message that your platform doesn't support passkeys even if it technically does. That's not really a situation where the RP is trying to break the spec or cause trouble, and it's not a situation where the provider is breaking spec either -- the entire thing is happening outside of spec. But having better error messages beyond "your device doesn't support passkeys" or "an error occurred" would make that situation clearer for end users who are confused why their browser or platform that "supports passkeys" doesn't work with every site.

I suspect even without attestation or purposeful blocking, situations like that are going to occasionally arise -- and it would be nice for providers who try to register with RPs and get back error messages to be able to know "am I blocked, or is something going wrong with the implementation, or is this a separate error, or...". Honestly, some of it even just comes down to debugging -- if you're an RP and registration with a provider breaks and you weren't trying to block them, whatever issues did come up will get fixed faster if the provider isn't just guessing what went wrong or whether they're blocked.

There's no way (short of adding certification requirements to RPs, which I can't imagine is going to happen) to require an RP to implement any part of the spec, but there are parts of the spec for RPs that are listed as requirements vs just optional suggestions.

mimi89999 commented 5 months ago

A vault could have been unlocked 8 hours ago and the user stepped away after 1 hour.

Yet their database is still unlocked. Which means (since you are assuming an attacker scenario here) I can simply copy your passkey data (and everything else) from your database and do an auth on my own terms. After all, this is entirely client side reported compliance, and the RP has absolutely no way to verify/validate this ever happened.

What I am saying is we have a mechanism to do user verification that actually matters, and that involves locking your database when you aren't using it.

This implementation is not spec compliant and has the potential to be blocked by relying parties.

How can relying parties even know? It's just a self reported boolean value.

@droidmonkey how could an attacker do that? UV should also be required for exporting the database. On many OSes UV is required to gain root/Admin access, so authentication would be required to dump KeePassXC memory.

droidmonkey commented 5 months ago

Physical or remote access to an unlocked computer and database, which the scenario presented assumes.

You can read a comprehensive dialog about requiring credentials prior to export or other similar action and why that is total security theatre: https://github.com/keepassxreboot/keepassxc/issues/9339

pamperer562580892423 commented 5 months ago

A vault could have been unlocked 8 hours ago and the user stepped away after 1 hour.

Yet their database is still unlocked. Which means (since you are assuming an attacker scenario here) I can simply copy your passkey data (and everything else) from your database and do an auth on my own terms. After all, this is entirely client side reported compliance, and the RP has absolutely no way to verify/validate this ever happened.

What I am saying is we have a mechanism to do user verification that actually matters, and that involves locking your database when you aren't using it.

As a normal user... about unlocked database in KeePassXC... I think you are aware of it, but maybe it is a bit risky, that the user is able to see the passkey data. I also use Bitwarden and I only see "a passkey is there" - and not the data behind it (let alone being able to manipulate the passkey-data itself). But in KeePassXC you could delete part of the passkey, edit parts of the passkey, copy the values... and when my database is unlocked, everyone else could do the same (of course, unlocked databases in and of itself are an error when leaving the computer - and this was and still is the same for every password in the database, so not a new "problem")... But still, I wonder whether this is as secure as it should be. 🤔

droidmonkey commented 5 months ago

We are not in the business of obfuscating or hiding data from the end user. Our users are generally sophisticated and aware of security practices. If they are not, then they won't likely be looking in the advanced tab anyway.

Hunterrules0-0 commented 5 months ago

I love 2fa and passkeys keys even though its impossiable to crack a modern secure password and the only reason we have 2fa is data breaches and idiiots who cant use their computer I love owning nothing and having no passwords I hate having the convince of a password I want passkeys image

pamperer562580892423 commented 5 months ago

We are not in the business of obfuscating or hiding data from the end user.

@droidmonkey Thanks for your reply! And understandable, too. - But how about some "middleground" in the long run? Not "obfuscating and hiding", but maybe at least require to re-enter your master password to be able to watch/edit/etc. passkey-data? So that there is one more security measure to/before "full passkey-access".

Our users are generally sophisticated and aware of security practices. If they are not, then they won't likely be looking in the advanced tab anyway.

You have not met my father. When something doesn't work, he would open every tab and try a click here and there... ;-)

pamperer562580892423 commented 5 months ago

PS: Ah, and possible re-entering of the master password, not only as a security measure against a "possible stranger", but also for the user itself, so that mistakenly manipulating with the data of a passkey (and rendering it useless thereby "by accident") is less likely... and BTW, I think you can't only think of the experts, only doing what is right at every turn, but also the beginner level user, who can damage a lot by trying silly things and maybe recognizing it four months later, when "something suddenly doesn't work"...