02.LAB · Hands-On

Passkey vs Password · Phishing

Same attacker. Same lookalike site. Two outcomes — the password gets stolen, the passkey doesn't even try.

An attacker registers chase-secure-login.com, sets up a pixel-perfect copy of Chase's login page, and sends phishing emails that link to it. The victim clicks. What happens next depends entirely on which credential they're about to use.

The two simulations below run the same attack against the same victim. The left side uses a password; the right side uses a passkey. Click "Submit" on each and watch the outcomes.

Victim's browser · Password flowAttack #1
https://chase-secure-login.com/signin
Chase Online™
Sign in to your account
Outcome

 

Victim's browser · Passkey flowAttack #2
https://chase-secure-login.com/signin
Chase Online™
Sign in with your passkey
Outcome

 

Why the password got stolen

The lookalike site asked for a username and password. The browser has no way to know the site is fraudulent. The user types real credentials. The attacker's web server receives them. The attacker then logs into the real chase.com using those credentials — from their own machine, in their own country — and the account is theirs.

Why the passkey refused

A passkey is a public-key credential bound to a specific origin at registration. When the user registered their Chase passkey, the browser tied that credential to the exact origin https://chase.com. The credential cannot be presented to any other origin. Not chase-secure-login.com. Not chase.com.attacker.io. Not even http://chase.com (different scheme).

When the lookalike site invoked WebAuthn to ask for an assertion, the browser checked the calling origin against the credentials stored for that origin. There was no credential registered for chase-secure-login.com, so the browser returned an error. The user's authenticator (phone, YubiKey, Touch ID) was never even consulted. The attack failed at the browser layer — before the user had a chance to make a mistake.

What actually happens at the protocol layer

When a site calls navigator.credentials.get({publicKey: ...}), the browser packages a client data JSON object that includes the origin it was called from. The authenticator signs that JSON. The server then verifies two things: that the signature is valid, AND that the origin in the signed data matches the server's expected origin.

{ "type": "webauthn.get", "challenge": "a7f3...b9c2", "origin": "https://chase-secure-login.com", // signed by the authenticator "crossOrigin": false }

If the attacker captures this signed assertion and replays it to the real chase.com, the real Chase server reads the signed origin field and sees chase-secure-login.com. Mismatch. The login is rejected. The cryptography itself encodes the destination, so a credential stolen from a wrong-origin site cannot be replayed to the right-origin site.

The four protections, stacked

Passkeys defeat phishing because the design stacks four protections:

A password defeats none of these. It has no origin awareness, no signature, no hardware binding, no asymmetry. The same string you typed on the phishing site is the string that grants access to the real site. That equivalence is what every password phishing attack exploits.

What this lab does not show

Passkeys defeat credential phishing. They do not defeat every attack:

The point

Passwords fail to phishing because the credential doesn't know where it's supposed to go. Passkeys succeed against phishing because the cryptographic primitive itself encodes the destination. There is no way to fool a passkey into signing for the wrong site.

This is the single most important shift in consumer authentication in twenty years. It is also the reason every major bank, every cloud provider, and every operating system is pushing passkey adoption: the attack surface that drives the largest category of account takeovers structurally vanishes.

References

Formatted in APA 7. Alphabetized by first author's last name.

  1. FIDO Alliance. (n.d.). Passkeys: A new era of secure sign-ins. https://fidoalliance.org/passkeys/
  2. Grassi, P. A., Fenton, J. L., Newton, E. M., Perlner, R. A., Regenscheid, A. R., Burr, W. E., Richer, J. P., Lefkovitz, N. B., Danker, J. M., Choong, Y.-Y., Greene, K. K., & Theofanos, M. F. (2017). Digital identity guidelines: Authentication and lifecycle management (NIST Special Publication No. 800-63B, Rev. 3). National Institute of Standards and Technology. https://doi.org/10.6028/NIST.SP.800-63b
  3. World Wide Web Consortium. (2021). Web Authentication: An API for accessing public key credentials, level 2. https://www.w3.org/TR/webauthn-2/