Passkeys Pwned: Turning WebAuthn Against Itself

Shourya Pratap Singh, Jonny Lin, Daniel Seetoh

DEF CON 33 · Day 2 · Main Stage

Overview

Passkeys are widely positioned as the successor to passwords — phishing-resistant, cryptographically bound to origins, and immune to replay attacks. Google, Apple, Microsoft, and major enterprise plat

Watch on YouTube · Slides

Visual summary for Passkeys Pwned: Turning WebAuthn Against Itself by Shourya Pratap Singh, Jonny Lin, Daniel Seetoh
Visual summary for Passkeys Pwned: Turning WebAuthn Against Itself by Shourya Pratap Singh, Jonny Lin, Daniel Seetoh

Key moments

  1. 2:29 Introduction: Passkey security model and adoption
  2. 7:29 WebAuthn protocol internals and attack surface
  3. 8:07 Credential management vulnerabilities in passkey implementations
  4. 17:29 Passkey phishing: turning WebAuthn's anti-phishing protection against itself
  5. 22:29 Account takeover via passkey manipulation
  6. 16:06 Live demo: exploiting passkeys to compromise authenticated sessions
  7. 1:01 Browser-specific passkey implementation weaknesses
  8. 37:29 CVE disclosures for passkey vulnerabilities
  9. 42:29 Recommendations for secure passkey deployment

Passkeys Pwned: Turning WebAuthn Against Itself

Speakers: Shourya Pratap Singh, Jonny Lin, Daniel Seetoh

Conference: DEF CON 33

YouTube: https://www.youtube.com/watch?v=GG4gAhbhPH8

Slides: https://media.defcon.org/DEF%20CON%2033/DEF%20CON%2033%20presentations/Shourya%20Pratap%20Singh%20Jonny%20Lin%20Daniel%20Seetoh%20-%20Passkeys%20Pwned%20Turning%20WebAuthn%20Against%20Itself.pdf

Overview

Passkeys are widely positioned as the successor to passwords — phishing-resistant, cryptographically bound to origins, and immune to replay attacks. Google, Apple, Microsoft, and major enterprise platforms have all pushed hard for passkey adoption, marketing them as the end of credential theft as we know it. At DEF CON 33, researchers Shourya Pratap Singh, Jonny Lin, and Daniel Seetoh from Square X — a browser security company — presented a systematic attack analysis of the WebAuthn protocol as implemented in modern browsers, demonstrating that the trust boundaries within the browser's WebAuthn mediation layer can be exploited to undermine the very properties passkeys are supposed to guarantee.

The team's research, which builds on prior work presented at DEF CON 32, identifies implementation-level attack vectors that fall outside the threat model passkeys were designed to address. Rather than attacking the cryptographic primitives, they exploit the browser's role as a trusted mediator between the authenticator and the relying party — showing that this mediation can be manipulated by malicious web content, browser extensions, and adversary-in-the-middle scenarios operating at the client side.

Background

▶ Watch: Browser-specific passkey implementation weaknesses (1:01)

Why Passkeys Were Built

Traditional password authentication has three fundamental problems that have proved essentially unsolvable at scale:

  1. Phishability: Users can be redirected to a spoofed login page and their credentials captured, since passwords have no binding to the origin domain.
  2. Guessability: Weak or reused passwords can be brute-forced or found in credential dump databases.
  3. Server-side exposure: When a service is breached, stored password hashes (or plaintext passwords) become attacker-controlled credentials valid everywhere the user reused the password.

Passkeys address all three through public-key cryptography:

  • Origin binding: The private key signs a challenge from the relying party, and the signature includes the relying party ID derived from the origin. A forged login page at a different origin will request a signature with a different relying party ID, which the authenticator will not produce for a passkey registered to the legitimate origin.
  • Non-guessability: The private key is a randomly generated asymmetric key stored on the authenticator device, never transmitted to the server.
  • Server-side safety: Only the public key is stored on the server. A server breach exposes no material that can be used to authenticate.

WebAuthn and FIDO2

The implementation of passkeys in browsers relies on the FIDO2 standard, of which WebAuthn (Web Authentication API) is the browser-facing specification. Two flows are central:

Registration flow:

  1. User initiates passkey creation on a website.
  2. Server generates a challenge and sends it with relying party information.
  3. Browser calls navigator.credentials.create(), passing this information to the authenticator.
  4. Authenticator prompts for biometrics or PIN, generates a key pair, stores the private key, and returns: credential ID, public key, attestation statement, counter value, and flags (user present/verified).
  5. Browser formats and returns this data to the server, which stores the public key and credential metadata.

Authentication flow:

  1. User initiates sign-in with passkey.
  2. Server generates a challenge.
  3. Browser calls navigator.credentials.get(), passing the challenge and allowed credential IDs.
  4. Authenticator prompts for biometrics/PIN, retrieves the private key, increments the replay-prevention counter, creates authenticated data, and signs it.
  5. Browser returns the signature, credential ID, and authenticator data to the server.
  6. Server verifies the signature against the stored public key and validates the counter increment.

The Browser as Trusted Mediator

A critical but underappreciated aspect of this architecture is the browser's role. The browser is the entity that:

  • Calls navigator.credentials.create/get()
  • Receives the authenticator's response
  • Formats and returns the response to the server's JavaScript

This means the browser sits between the authenticator (hardware or platform) and the server (relying party). If the browser can be compromised or manipulated, it occupies a position capable of interfering with the integrity of both registration and authentication flows.

Key Findings

▶ Watch: WebAuthn protocol internals and attack surface (7:29)

The Square X research team identified multiple attack categories that exploit the browser's mediation role:

1. Credential Interception via Malicious Browser Extensions

Browser extensions operate at elevated privilege relative to normal web content. A malicious extension can:

  • Hook navigator.credentials.create/get(): By overriding these APIs at the browser extension level, an extension can intercept registration and authentication flows.
  • Capture or substitute credential data: The extension can capture the authenticator's response before it reaches the relying party's JavaScript, or substitute a different credential ID/signature combination.
  • Perform credential registration on behalf of the attacker: During a legitimate registration flow, an extension can silently invoke a second navigator.credentials.create() call registering an attacker-controlled credential on a server that does not enforce strict registration count limits.

The attack exploits the fact that navigator.credentials.create/get() are JavaScript APIs — and JavaScript APIs can be overridden by content scripts and extension service workers.

2. Adversary-in-the-Middle at the Browser Layer

Unlike traditional phishing (which passkeys are designed to defeat at the origin-binding level), a client-side adversary-in-the-middle can:

  • Operate at the same origin as the legitimate website (injected via a compromised CDN, XSS, or browser extension).
  • Call navigator.credentials.get() using the legitimate origin's relying party ID.
  • Receive a valid, origin-bound signature — because the authenticator sees the correct origin and legitimately produces the signature.
  • Forward or replay this signature to the relying party server to authenticate.

This is distinct from a network-level MITM because it operates within the trust boundary of the correct origin, defeating origin binding entirely.

3. Challenge Manipulation

The authentication challenge is the server's primary anti-replay mechanism. The sequence is:

  1. Server generates a fresh, random challenge.
  2. The authenticator signs a payload that includes this challenge.
  3. Server verifies the signed payload contains its expected challenge.

A client-side adversary can manipulate this flow by:

  • Intercepting the challenge before it reaches navigator.credentials.get().
  • Substituting a known or attacker-controlled challenge.
  • Using a pre-obtained, pre-signed response to authenticate.

For this to work, the attacker must either obtain a valid signed response for their chosen challenge (possible if they can trigger an authentication on a victim's device) or coerce the victim into authenticating against the attacker's challenge.

4. Credential Enumeration and Account Correlation

WebAuthn's navigator.credentials.get() can be invoked with specific credential IDs or with an empty allow-list (triggering the authenticator to show all available credentials for the current relying party ID). Research identified cases where:

  • Variations in authenticator behavior (timing, error messages, UI prompts) could reveal whether specific credential IDs are present.
  • Correlation attacks using credential IDs across multiple relying parties could de-anonymize users who use the same authenticator for multiple services.

Technical Deep Dive

▶ Watch: Live demo: exploiting passkeys to compromise authenticated sessions (16:06)

The JavaScript API Surface as an Attack Plane

The fundamental architectural tension is that WebAuthn's security properties are designed around the assumption that navigator.credentials.create/get() are tamper-proof system-level calls. In practice, they are JavaScript functions that:

  • Exist in the browser's JavaScript engine namespace.
  • Are accessible to all JavaScript running in the same context (including extension content scripts).
  • Return JavaScript objects that can be inspected, copied, or modified before being passed to server-side verification code.

A proof-of-concept hook on navigator.credentials.get() looks structurally like any other API override:

This override is invisible to the website's own JavaScript and to the server. The authenticator performs its biometric check and produces a valid signature — but the interception point is after the authenticator and before the relying party's verification code.

Extension Privilege Model

Browser extension content scripts run in an "isolated world" that shares the DOM with page JavaScript but has a separate JavaScript environment. However, extensions can inject scripts into the page's main world using chrome.scripting.executeScript with world: "MAIN" — placing their code in the same namespace as the page's JavaScript. This allows the API override technique described above to work transparently from within an extension.

Counter Bypass Implications

The authenticator counter is designed to detect cloned authenticators: if a server sees a counter value lower than the last seen value for a credential, it should reject the authentication (since the authentic device should always have incremented it). However:

  • Servers are not required to enforce counter checks and many do not in practice.
  • A client-side interception of a valid signature does not require forging counter values — the interceptor receives the legitimate signed data including the current counter value.
  • If the signature is used once and discarded, counter verification will pass.

Demo / Proof of Concept

▶ Watch: Account takeover via passkey manipulation (22:29)

The Square X team demonstrated several attack chains live:

  1. Extension-based credential capture: A benign-looking browser extension (no suspicious permissions in the manifest beyond what typical utility extensions request) hooked navigator.credentials.get(). During a demonstration authentication flow on a test relying party, the extension silently captured the WebAuthn assertion — credential ID, signature, authenticator data — and exfiltrated it to an attacker-controlled server. The legitimate user authenticated successfully (from their perspective), and the attacker simultaneously obtained a valid assertion.
  1. Silent second registration: During a registration flow, the extension triggered a second navigator.credentials.create() call with attacker-controlled parameters, registering an additional passkey on the test server without any user-visible prompt or indication.
  1. Challenge manipulation demonstration: By intercepting and substituting the challenge in the options object passed to navigator.credentials.get(), the researchers demonstrated that in implementations where server-side challenge verification was weak, a previously-obtained signed response could be replayed.

The demos underscored that these attacks are not theoretical edge cases — they require only the extension installation step, which is consistent with the threat model of a compromised or malicious browser extension.

Defensive Implications

▶ Watch: Recommendations for secure passkey deployment (42:29)

For Developers Implementing Passkeys

  • Enforce server-side challenge verification strictly. Every authentication attempt must be verified against the specific challenge issued for that session. Do not reuse challenges or accept signatures from expired sessions.
  • Implement counter validation. While many authenticators do not increment counters (particularly platform authenticators on mobile), for hardware security keys, counter validation provides a meaningful defense against replay of intercepted assertions.
  • Audit concurrent credential registrations. Implement rate limiting and anomaly detection on registration events. A legitimate user should not register multiple credentials in rapid succession without explicit multi-device enrollment flows.
  • Enforce attestation verification. Attestation allows the server to verify that the credential was created by a legitimate authenticator. While attestation is often skipped for privacy reasons, high-security applications should require it.
  • Consider post-quantum readiness. The elliptic curve cryptography underlying FIDO2 (typically ES256 or RS256) will eventually be vulnerable to quantum attacks. FIDO Alliance is tracking post-quantum algorithm integration.

For Browser Vendors

  • Restrict content script access to credential API responses. The navigator.credentials API should be marked as non-overridable or should be implemented at a level below the JavaScript namespace accessible to extension content scripts.
  • Alert users to credential API interception. Browsers could surface warnings when extension code is detected attempting to override or wrap the credentials API.
  • Implement API integrity monitoring. Browser security features like Trusted Types have set precedent for protecting DOM API integrity; equivalent protections for authentication APIs are warranted.

For Users

  • Audit browser extensions. Malicious extensions are the primary practical attack vector demonstrated. Minimize installed extensions and prefer those from verified publishers with limited permissions.
  • Use hardware security keys for high-value accounts. Physical FIDO2 security keys (YubiKey, etc.) provide a stronger guarantee than platform authenticators for accounts where authentication integrity is critical.
  • Enable attestation where available. For enterprise environments, requiring attested authenticators provides server-side verification of authenticator legitimacy.

Key Takeaways

  1. Passkeys defeat network-level phishing and server-side credential theft, but not client-side interception. The threat model has shifted from the server to the browser.
  2. The browser is not a trusted computing base. Its role as mediator between authenticator and server creates an attack surface that cryptographic origin binding alone cannot close.
  3. Browser extensions represent the primary practical attack vector. Extension privilege to override JavaScript APIs in the page context is sufficient to intercept WebAuthn flows.
  4. Server-side implementation quality matters. Weak challenge verification, absent counter validation, and missing attestation enforcement reduce passkeys to weaker security guarantees than intended.
  5. Passkeys have not undergone the same adversarial research depth as passwords. The field is years behind where password security research was by the time passkeys are reaching mainstream adoption — this gap needs to close rapidly.

About the Speakers

Shourya Pratap Singh is a Principal Software Engineer at Square X, a browser security company. This was his second DEF CON appearance and second main stage talk, reflecting an active research track in browser-based authentication security.

Jonny Lin is a front-end engineer and security researcher at Square X. This was his first DEF CON presentation.

Daniel Seetoh is a Senior Front-End Engineer at Square X. Also presenting at DEF CON for the first time, Daniel contributed significantly to the WebAuthn flow analysis and technical demonstration components of the research.

The Square X team has presented related browser security research at DEF CON 32, establishing a research program focused on how browser-layer threats undermine web authentication and security primitives.

Reviews

Dr. Zero (Offensive Security Researcher) — SOLID

Square X maps the attack surface of passkeys at the browser mediation layer, demonstrating that WebAuthn's cryptographic guarantees dissolve when a malicious extension can override navigator.credentials API calls.

Heather Calloway (CISO) — SOLID

Square X researchers demonstrate that passkeys, while defeating network-level phishing and server-side credential theft, are vulnerable to client-side attacks via malicious browser extensions that can intercept, capture, or substitute WebAuthn credential flows—shifting the threat model from the server to the browser without the industry having fully caught up to the change.

→ Top-rated talks at DEF CON 33

All talks from DEF CON 33