Skip to content

PATTERN Cited by 1 source

Password manager as phishing guardrail

Pattern

Use a password manager's browser plugin as a secondary phishing control: the plugin will only autofill on a URL that matches the domain the credential was saved against. A phisher's lookalike domain (members-x.com vs x.com) triggers a silent refusal to autofill — which, if the user notices, is a strong signal that the current page is not the real site.

Why it kind-of works

  • Domain match is a poor-man's origin check. It's not as strong as WebAuthn's cryptographic origin binding — the password manager just refuses to type the credentials; the credentials themselves are still un-bound to an origin and would be replayable if the attacker obtained them by other means. But it's free and opt-out-by-default: as long as the user only ever clicks the autofill button, the plugin's domain check is enforced.
  • Catches the lookalike-domain casemembers-x.com, homoglyph attacks, subdomain confusions, TLD swaps. All stop at the plugin's refusal.
  • No user judgement required. The user doesn't have to notice the URL is wrong; they just have to notice that the autofill didn't happen.

Cf. Fly.io's 2025-10-08 postmortem:

"Kurt complains that 'x.com' is an extremely phishable domain, and, sure, but also: the 1Password browser plugin would have noticed that 'members-x.com' wasn't an 'x.com' host." (Source: sources/2025-10-08-flyio-kurt-got-got)

Why it failed for Fly.io

Kurt pulled the credential manually from 1Password and copy-pasted it into the lookalike site. The browser plugin's domain check is bypassed whenever the user switches from autofill to manual retrieval:

  • Copy-password-to-clipboard mode
  • Reveal-password + retype
  • Mobile-without-the-plugin flows
  • Password-manager desktop app (vs browser plugin)

Any of these routes around the plugin's origin check. The credential is just a string; the plugin's protection is only applied at the autofill seam.

Why it's a weak control, not a primary one

The password manager is a stringly-typed shared secret store. The protection is a client-side behavioural check layered over an intrinsically phishable primitive (password + OTP). Compare to WebAuthn, where the primitive itself is origin-bound at the cryptographic layer — no amount of user misbehaviour can cause the authenticator to produce a usable assertion for the wrong origin.

Control Strength How it's defeated
Password manager autofill domain check Medium User manually copies credential
Phishing training Low User clicks under pressure
OTP / push MFA Low Reverse-proxy phishing kit replays within the window
WebAuthn / FIDO2 / Passkey High Not defeated by user behaviour; only by compromise of the authenticator itself

Composition with the stronger pattern

In an patterns/phishing-resistant-mfa-behind-idp regime, the password manager is not on the critical path for IdP-covered apps — the IdP itself is. The password manager is the secondary hygiene control for accounts that can't be federated (the legacy shared accounts). In Fly.io's case: Twitter/X was in 1Password exactly because it couldn't be behind Google SSO. The pattern's residual value is: when you can't get FIDO2, at least get autofill-only discipline + unique password per account.

Operational hardening

  • Forbid manual copy-paste as org policy. If the plugin won't fill it, don't sign in. Kurt's phish would have been blocked by this rule alone.
  • Use the password manager's domain-variant warning (most major managers warn on domain similar-but-not-equal).
  • Minimise the account's shared-credential population. One holder is strictly safer than five.
  • Push everything onto the IdP as soon as it's feasible. The password manager is the fallback, not the goal.
  • Prefer passkey-in-manager over password-in-manager where the platform supports it — 1Password, iCloud Keychain, Google Password Manager all store passkeys now, which restores the origin-bound property at the authenticator layer.

Seen in

  • Fly.io Kurt Got Got (2025-10-08) — canonical wiki instance. 1Password browser plugin explicitly named as the control that would have blocked the phish had Kurt autofilled. The manual-copy-paste failure mode is named as the reason it didn't. Post-incident fix is to move the account onto Passkeys, which relocates the protection from plugin-side behavioural check to authenticator-side crypto (sources/2025-10-08-flyio-kurt-got-got).
Last updated · 517 distilled / 1,221 read