keepassxc-browser icon indicating copy to clipboard operation
keepassxc-browser copied to clipboard

Passkey man-in-the-middle attack

Open DigitallyRefined opened this issue 1 year ago • 8 comments

Expected Behavior

Passkeys should not be sent or saved when the websites TLS/SSL certificate is invalid.

Current Behavior

Passkeys are sent and saved when the websites TLS/SSL certificate is invalid.

For example, if the user connects to an untrusted network which resolves the DNS to an attackers server (with an invalid TLS certificate) and they accept the warning and continue, they can still use their passkey to login and the attacker would then have access to their account by replaying the users passkey challenge to the original server.

When KeePassXC is closed, KeePassXC Browser falls back to Chrome/Chromium's built in passkey system, which throws a WebAuthn JavaScript exception with an invalid TLS error.

Possible Solution

The KeePassXC Browser extension should validate that the website is secure (over HTTPS) and has a valid TLS certificate before sending or saving passkeys (only localhost is allowed to use insecure HTTP for development).

Steps to Reproduce (for bugs)

  1. Setup KeePassXC and KeePassXC Browser to allow Passkey storage
  2. Visit a website with an invalid certificate that allows logging in via Passkeys
  3. Accept the invalid certificate warning and continue
  4. Login or register

Screencast from 2024-02-19 19-32-37.webm

Debug info

KeePassXC - 2.8.0-snapshot KeePassXC-Browser - 1.8.12 Operating system: Linux x86_64 Browser: Chrome/Chromium 121.0.0.0

DigitallyRefined avatar Feb 19 '24 20:02 DigitallyRefined

I find it interesting that it is so trivial to bypass the built-in Chrome/ium safeguards (in this case inadvertantly). We override the passkey handling function, which apparently does this check when not overridden. We have to override it because no browser supports thirdparty passkey authenticators. Well looks like they need to move more stuff outside that function.

https://lists.w3.org/Archives/Public/public-webauthn/2022Nov/0135.html

droidmonkey avatar Feb 19 '24 20:02 droidmonkey

For Firefox this can be achieved by using: https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/webRequest/getSecurityInfo

varjolintu avatar Feb 20 '24 16:02 varjolintu

For reference, this seems to be Mozilla's native implementation:

  • https://github.com/mozilla/gecko-dev/tree/master/dom/credentialmanagement
  • https://github.com/mozilla/gecko-dev/blob/master/dom/webidl/CredentialManagement.webidl#L21

phoerious avatar Feb 20 '24 16:02 phoerious

TBH, I'm quite ambivalent on this. Yes, it's probably safer to refuse to provide credentials when the certificate is invalid. On the other hand, you have consented to this kind of MITM when you accepted the security exception for this certificate. In the end, accepting an invalid certificate means you checked its validity yourself, hence the connection is indeed secure, despite what the red padlock says.

phoerious avatar Feb 20 '24 17:02 phoerious

And just to note: KeePassXC side already ignores a requests that are made without a HTTPS scheme.

varjolintu avatar Feb 20 '24 17:02 varjolintu

TBH, I'm quite ambivalent on this. Yes, it's probably safer to refuse to provide credentials when the certificate is invalid. On the other hand, you have consented to this kind of MITM when you accepted the security exception for this certificate. In the end, accepting an invalid certificate means you checked its validity yourself, hence the connection is indeed secure, despite what the red padlock says.

That's true, but users being users might just click past the warnings without understanding the consequences (especially if they've encountered the TLS error/warning before). But I suppose if they've installed KeePassXC and the browser extension and turned on Passkeys, then then perhaps they should know better than just to skip past the certificate error warning messages!

I did test this out of curiosity on Firefox 122 and Safari 17.3.1 (without KeePassXC) and both of them allow you to login and register Passkeys even when the TLS certificate is invalid, surprisingly. It seems that only Chrome/Chromium 121 throws a Uncaught (in promise) NotAllowedError: WebAuthn is not supported on sites with TLS certificate errors. but that could be the @simplewebauthn/browser NPM module I'm using.

DigitallyRefined avatar Feb 20 '24 18:02 DigitallyRefined

Not to mention, you would break the ability to use passkeys for dev and local hosted services (like a NAS, for example) unless you also set up a CA and other bits to make them legit certs. Overall, any enterprise worth their salt is disabling the users' ability to bypass invalid certs.

droidmonkey avatar Feb 20 '24 19:02 droidmonkey

Modern browsers make it hard enough to skip certificate validation errors. The red screen is pretty scary and you have to first find and then click a tiny "Advanced options" link, read through some more tech babble and then click "Proceed anyway". In some cases, Chrome doesn't even show this option and you have to blindly type "thisisunsafe" to proceed. If you did all that are still willing to enter your password after this, you may deserve what's coming.

phoerious avatar Feb 20 '24 20:02 phoerious

Closing this, as the browsers built in certificate error page should be enough to warn users not to continue and if they do they shouldn't be using their passkeys.

DigitallyRefined avatar Apr 14 '24 11:04 DigitallyRefined