#13667·keepassxc

Bitwarden import: non-UUID `credentialId` silently becomes the null UUID, breaking imported passkeys

Author: xrxss15Created Sep 12, 2026Updated Sep 13, 2026
Labelshigh priority :rotating_light:feature: Passkeysimport: Bitwarden

Have you searched for an existing issue?

  • Yes, I tried searching and reviewed the pinned issues

Brief Summary

Summary

BitwardenReader.cpp:92-98 treats login.fido2Credentials.credentialId as a UUID. My export contained a credentialId in a different form — base64url with a b64. prefix. The conversion does not fail on it; it produces the null UUID, so the entry imports without error and KPEX_PASSKEY_CREDENTIAL_ID ends up as AAAAAAAAAAAAAAAAAAAAAA. The passkey then cannot authenticate.

Root cause

cpp
const auto credentialUuid = Tools::uuidToHex(credentialIdValue);   // QString -> QUuid, implicit
const auto credentialIdArray = QByteArray::fromHex(credentialUuid.toUtf8());

Tools::uuidToHex() takes a QUuid. The QString is converted implicitly, and an unparseable value yields a null QUuid rather than an error. toRfc4122() returns 16 zero bytes, the hex round-trip preserves them, and the base64url encoding is 22 A characters. Nothing on the path reports a failure.

This affects any credentialId that is not a UUID, not only the b64. form.

Environment

  • KeePassXC 2.7.12, Windows
  • Source vault: Bitwarden Password Manager for Android 2026.8.1 (21856)

Related

#10775 and discussion #10716 consider only the UUID form.

Steps to Reproduce

  1. Bitwarden vault export, unencrypted .json, containing a passkey whose credentialId is b64.-prefixed base64url rather than a UUID.
  2. KeePassXC 2.7.12: Database → Import → Bitwarden (.json).
  3. Entry → Advanced: KPEX_PASSKEY_CREDENTIAL_ID = AAAAAAAAAAAAAAAAAAAAAA.
  4. Authentication with the imported passkey fails.

tests/data/bitwarden_passkey_export.json covers the UUID form only, so this variant is untested.

Expected Versus Actual Behavior

No response

KeePassXC Debug Information

Operating System

Windows

Linux Desktop Environment

None

Linux Windowing System

None

Source: keepassxreboot/keepassxc