Bitwarden caveats: password history, asterisk-corruption bug on router logins, autofill pitfalls, and recovery steps
Find a file
Repository files (latest commit first)
Filename Latest commit message Latest commit date
2026-10-12 06:04:47 -05:00
README.md docs: add Gmail/Brave built-in password manager case (two mechanisms: stale credential vs Google passkey friction) 2026-10-12 06:04:47 -05:00

Bitwarden Caveats

Real-world failure modes of Bitwarden worth documenting, with recovery steps so you are never locked out.

Status: verified against Bitwarden docs and issue trackers, October 2026. TL;DR: Bitwarden does keep old passwords (item history + generator history), so a corrupted entry is usually recoverable. Never click Update unless you just changed the password yourself.


The incident: router login page

The scenario that prompted this document:

  • Router login page (a name + a password — looks trivial) does not autofill.
  • Copy/paste works, so that was the habit.
  • While logged in, a popup appears: "Update existing login?" Clicking it saves literal asterisks/bullets (***/...) as the password instead of the real value.
  • You don't notice until the next login. By then the vault holds garbage, copy/paste gives you garbage, and you appear locked out of the router.

This is real, known, and not your fault. What actually happened under the hood:

  1. Many router web UIs (and other JavaScript-heavy login pages) replace the content of the password field with bullet/asterisk characters before their scripts are done with it.
  2. If Bitwarden reads the field at that moment — which is exactly what happens when you submit and then get the "update" popup — it stores the literal dots/asterisks.
  3. This is tracked upstream as bitwarden/browser#2288 ("Autosave is saving literal ............... as the password for some sites"). A related false-positive bug in the browser extension (2025.11.x) also prompted "update existing login" for unchanged passwords; clicking Update could overwrite your entry. Fixed in extension 2025.12.0.
  4. There was also a browser-extension regression in 2025.11.0/2025.11.1 that produced unwarranted "update existing login" prompts (see references).

Golden rule: only click Update (or Add) when you have just changed the password yourself. If you did not change it, don't click — treat the prompt as noise, not as a net you fell into.


Does Bitwarden keep old passwords? Yes — two histories

1. Item Password History (per login item, synced)

  • When a password (or a hidden custom field) is changed, the prior value is kept.
  • Retains the last five saved values per item (including items sitting in the Trash, until permanently deleted).
  • Survives logout, other devices, and sync.
  • Where to look: open the vault item → Edit → scroll to the bottom → Password History (click the eye to reveal values, use the timestamps to identify which is which).

This is the recovery path for the incident: when the "update" popup wrote asterisks over your real password, the real password moved into Password History.

2. Generator History (local, per device)

  • Every password generated in the generator is stored (up to the last ~100 entries).
  • Not synced — it is local to the device, and cleared when you log out.
  • Where to look: Generator tab → History (bottom of the window).

If you changed the router password to a strong generated value, but never actually saved it into the vault correctly, it is almost certainly in Generator History on the machine where you generated it. Check it before logging out.

The failure case

History only keeps ~5 entries per item. If the entry is overwritten with junk more than five times (e.g. clicking "Update" on many logins), the real password rolls off the end. After that, the only guaranteed router recovery is a physical factory reset (hold the reset button ~10s) and reconfigure.


Recovery steps (do these in order)

  1. Update the Bitwarden browser extension to the newest version (≥ 2025.12.0).
  2. Kill the dangerous popups: extension → Settings → Notifications → uncheck:
    • Ask to add login
    • Ask to update existing login
  3. Open the affected login item → Edit → Password History. Reveal each entry and match it against the dates you changed router passwords. The previous real password should be there.
  4. Check Generator → History for the current strong password you set on the router.
  5. Repair the item: set the password to the router's actual current password, save. Verify by logging in.
  6. Nothing usable in history? Physical reset of the router and start over (routers cannot be recovered any other way — no vendor backdoor for a forgotten password).

Why router autofill doesn't work (and how to fix it)

Most common causes, all known and documented:

Symptom Cause Fix
No match at all (badge counter 0 on the extension icon) URL saved as https://… but page is http://192.168.x.x, or default match detection doesn't handle raw IPs/local hostnames (e.g. synology:5000) Store the exact URL and set the login item's match detection to "Host" (Settings → Autofill → Default URI Match Detection)
Matches, but fields don't fill Nonstandard field id/name (e.g. identifierId, Passwd) or a hidden duplicate field Add Custom fields → type "Linked", name = the field's id/name, linked to Username/Password
Password visibly filled but login fails Router UI wipes/rewrites the autofilled value (Zyxel models are notorious), or password field is type text not password Copy/paste is the reliable fallback — see below
Nothing happens when using the inline autofill menu Known extension bug on some pages Click the extension icon and pick the item there, or use keyboard autofill (Ctrl+Shift+L)

Note: a "Not Secure" label is just http vs https — not why autofill fails.

Safe workflow for routers (and anything with broken autofill):

  1. Create/repair the login item in Bitwarden first — with the correct password.
  2. Enable the fix above (Host match detection) so the item shows up.
  3. Copy the password from the vault, paste it into the router (with the ugly popups disabled, there is nothing dangerous left to click).
  4. Never accept a save/update prompt from the router page itself. If you must change the router password, change it, then update the vault item manually (bit.ly-style: edit item → change password → save), with the old one still visible in the item's Password History as a safety net.

More caveats in this family (worth internalizing)

  • Clipboard clearing: Bitwarden can wipe copied values after N seconds; pasting after that yields nothing. Set a long delay or disable it if it surprises you.
  • Save prompts silently fail on many sites. Reliable pattern: create the entry in Bitwarden first, then autofill from Bitwarden to the site — never let the site feed Bitwarden.
  • Methodical password changes: when changing a password, paste the previous valid password into the item's Notes before saving the new one, so the good value can never roll out of history.
  • Master password is unrecoverable. The item passwords are recoverable (history); the master password is not. Keep the recovery code from setup.
  • Backups: periodically export an encrypted .json backup (Vault → Settings → Export). Exports include password history — a full restore with history is possible.
  • Two histories exist and behave differently: item history = synced, ~5 entries; generator history = local, ~100 entries, lost on logout. Know which one you are looking at.
  • 2FA/TOTP steps can trigger spurious save/update prompts on some sites (the 2025.11.x wave); if you see a prompt right after entering a TOTP code and you didn't change a password — dismiss it, don't click Update.

Two-factor authentication (Google Authenticator / TOTP): the same failure line, worse

Same pattern, harder recovery: the tool silently loses or never holds the correct secret, and you only discover it at login time. With a router you have a factory reset as the escape hatch; with TOTP there is no reset — if the seed and the backup codes are both gone, only the account vendor can help (or nobody).

How Google Authenticator locks you out

  • GA stores the 2FA seed only locally in the app on your phone. By default nothing is synced or backed up.
  • Lose the phone, wipe it, switch phones, or reinstall the app without a transfer → all codes are gone.
  • Every account protected by those codes then cannot be signed in to, unless you saved that site's backup codes or have a recovery email flow (usually slow, often gated).
  • Since 2023 GA offers optional cloud sync to your Google Account, but only if you deliberately enabled it — and users have reported sync not carrying over to a new phone. Note also that enabling it puts copies of your seeds behind that Google account.

Bitwarden specifics (where it gets "same or worse")

  1. 2FA on your Bitwarden account itself is the worst variant: lose the second factor and you're locked out of the entire vault. The only exit is the two-step recovery code shown when you enable 2FA — and it must be stored outside Bitwarden (print it, or keep it in a second manager). If you lose both the second factor and the recovery code, the vault is gone, master password or not.
  2. TOTP seeds stored inside vault items (Bitwarden's integrated authenticator autofills codes) are a single point of failure: lose the vault and you simultaneously lose the passwords and the 2FA codes for every account in it. Storing an account's seed in the same vault as its password also weakens the "second factor" idea.
  3. False save prompts on 2FA pages: during the 2025.11.x extension bug wave, Bitwarden offered to save the TOTP step as a new login item, creating junk entries that confuse autofill later. Same rule as the router: do not click Save/Update on a page where you did not just change a password.

Safe practice

  • Record the setup key (TOTP secret / QR) every time you enable 2FA. Store it in Bitwarden as a hidden custom field or on an offline printout. If the phone dies, the seed alone can rebuild the code in any authenticator app — this is the recovery equivalent of the router reset.
  • Keep the site's backup codes somewhere second (safe, offline). Sites print these at enable time exactly for this scenario.
  • Run 2FA on two independent devices/vendors (e.g. phone + a desktop authenticator like Ente Auth, Aegis, or a second phone) — no single lockout.
  • Never protect your Bitwarden account with a seed stored inside Bitwarden — that is circular (garbage-in, locked-out).
  • Prefer passkeys (FIDO2) where offered. They are more portable, but register a second device and keep a recovery path — a hardware key can be lost too.

Browser-built-in password managers (the Gmail / Brave case)

Same failure line, different tool: the manager silently holds the wrong credential and you only notice at login time. For Gmail the culprit was Brave's built-in password manager, not Bitwarden.

What actually happens (two mechanisms, both confirmed)

  1. Brave's built-in manager has known autofill/save defects (brave/browser#50782, brave/browser#58159 and many forum threads). It can save a stale value, or never offer the right entry, and on some platforms it doesn't reach passwords stored in Google Password Manager at all. Result: username+password login to Gmail just doesn't work.
  2. Google itself now de-prioritizes password sign-in. Google defaults to passkeys ("skip password when possible"); many accounts greet a correct password with a verification or passkey-only challenge and push you to phone-based methods. So the saved password may be right — the flow simply insists on something else.

Two quite different situations — check which one you're in.

Diagnosis (2 minutes)

  1. brave://password-manager/passwords → open the google.com (or accounts.google.com) entry → reveal → compare it to the password you actually use.
  2. In your Google account: Security → is "Skip password when possible" on? Do you have passkeys registered? Are there 2-Step Verification methods (phone, TOTP)?
  • Stored value ≠ real password → wrong saved credential (mechanism 1).
  • Stored value = real password but login still forced to phone → Google's passkey/verification friction (mechanism 2). No data loss — the phone methods are your working fallback, and "Try another way" on the login page can route back to password entry.

Recovery & fix

  • Mechanism 1 (wrong saved value): get in via the phone method, change the Gmail password, then delete the stale Brave entry and save the new one deliberately. Same "only save on the page where you just chose the password" rule as the Bitwarden popup.
  • Mechanism 2 (Google friction): keep your phone method registered, add a TOTP seed (authenticator) for the account in your Vaultwarden item so you have a non-phone 2FA path, and optionally register a passkey. This is a Google sign-in policy thing, not a password-manager bug.
  • Systemic fix — one source of truth: do not run two password managers (Brave built-in and Bitwarden/Vaultwarden) on the same accounts. In Brave: Settings → Passwords → disable "Offer to save passwords", and delete the Brave-saved entries for the accounts you manage in Vaultwarden. When a browser popup asks "save password?", treat it like the Bitwarden "Update" popup — only accept it on the page where you just chose that password.

Self-hosted (Vaultwarden): what changes, and what's worse

Context on this host: Vaultwarden at https://vault.2001a.us, SQLite DB in stacks/vaultwarden/data/. All client-side bugs above (asterisks, false update prompts, router autofill) apply unchanged — they live in the browser extension, not in the server. What changes is the boundary of the worst case.

  1. The DB is now the "factory reset" boundary. Losing stacks/vaultwarden/data/ loses every password and the password history in one shot — that is the single most dangerous dataset on this host.
  2. Backup pipeline (already in place here): ~/scripts — 05-dump-state.sh runs a consistent sqlite .backup of db.sqlite3 plus a copy of the full data/ dir and .env; 06-verify-restore.sh tests the staging dump; 08-restic-backup.sh snapshots it; systemd timer runs nightly. Two caveats:
    • The restic repo is currently local to the same host (/var/backups/restic-local); the plan itself flags the offsite target as unresolved. Until a second repo exists elsewhere, disk failure loses vault and backup together.
    • Confirm the timer is actually running and test a restore; a backup you've never restored is a guess.
  3. Password history is not part of CSV/JSON exports (long-standing open feature request). Only a database backup preserves the last-five password history. So: the sqlite .backup in the restic pipeline is exactly what protects the router-style recovery path.
  4. 2FA on the Vaultwarden account is recoverable by an admin — unlike hosted Bitwarden, where the recovery code is your only out. The admin panel (/admin → Users) can disable any user's 2FA. This is a safety net and a takeover path: everything on the panel is gated only by ADMIN_TOKEN, so keep it strong and lock /admin down. (An admin cannot read item secrets without the master password, but they can strip 2FA.)
  5. TOTP seeds stored in the vault live in that same DB — the DB backup preserves them, but they remain a single point of failure per the 2FA section above.

Suggestion: pin vaultwarden/server to an explicit version like the web-vault is already pinned, so homelab updates can't silently pull a newer image.


References


Last reviewed: 2026-10-12.