ANT-2026-0JJXMV3G · supabase/auth

privilege-escalation medium

Severity Claude medium · Security research firm - · Maintainer -

Discovered by Claude Mythos Preview

REPORT

Anthropic's analysis of this finding, sealed at approval.

ANT-2026-0JJXMV3G: Passkey registration requires no step-up authentication

The POST /passkeys/registration/begin and /finish handlers in internal/api/passkey_registration.go are protected solely by the requireAuthentication middleware, which accepts any valid access token. Unlike MFA factor enrollment, no AAL2, recent re-authentication, or password confirmation is required before binding a new WebAuthn credential. An attacker who has stolen a victim's bearer JWT (via XSS, malware, or leaked logs) can complete the registration ceremony with their own authenticator. Because passkeys serve as a primary sign-in method, the attacker retains access even after the victim rotates their password and revokes all sessions.

Target

Project: supabase/auth
Location: internal/api/passkey_registration.go:107
Discovery: static analysis — not yet dynamically reproduced

Technical Details

The registration endpoints are gated only by requireAuthentication (any valid access token) rather than a step-up check. There is no enforcement of AAL2, fresh re-authentication, or proof of an existing credential before a new WebAuthn authenticator is bound to the user, so possession of a session token alone is sufficient to add a persistent primary login credential.

Reproduction

  1. Attacker steals the victim's bearer JWT (e.g., via XSS on the operator's frontend).
  2. Attacker calls POST /passkeys/registration/begin with the stolen token and receives WebAuthn creation options.
  3. Attacker completes the WebAuthn ceremony with their own hardware key and POSTs to /passkeys/registration/finish.
  4. Server stores the attacker's credential against the victim's user record.
  5. Victim later changes password and revokes all sessions; attacker still signs in via /passkeys/authentication using the planted credential.

[No reproducer or sanitizer output attached — request from security-cvd@anthropic.com if needed.]

Suggested Fix

Require step-up authentication (fresh password entry, an existing passkey ceremony, or AAL2) before allowing a new passkey to be registered, and send an out-of-band notification to the user whenever a credential is added.

Acknowledgement

This vulnerability was discovered by Claude, Anthropic's AI assistant, and triaged by the Anthropic security team in collaboration with Anthropic Research. Please direct questions to security-cvd@anthropic.com and reference ANT-2026-0JJXMV3G.


Reference: ANT-2026-0JJXMV3G
Anthropic CVD Policy: https://www.anthropic.com/coordinated-vulnerability-disclosure

TIMELINE

Dates from discovery through public reveal.

  1. 2026-05-14 Reported to tracker
  2. 2026-05-14 Maintainer acknowledged
  3. 2026-05-15 Sent to maintainer
  4. 2026-06-04 Patch released
  5. 2026-08-18 Publicly revealed
PROVENANCE

SHA-3-512 hash:

266e4585a462c1297304b7868a86da419c2a64e3953f6e70bb5bf146646e27cc72942dcf203827eb14de71a63d4a9796e63a95030dadaf93aab3539449f63cff

Committed 2026-05-17 18:02 PT

Revealed 2026-08-18 07:12 PT

Verify (download preimage.json)

Show preimage JSON
{
  "ant_id": "ANT-2026-0JJXMV3G",
  "bug_class": "privilege-escalation",
  "claude_severity": "medium",
  "commit_sha": null,
  "created_at": "2026-05-14T22:00:24+00:00",
  "description": "The POST /passkeys/registration/begin and /finish handlers in internal/api/passkey_registration.go are protected solely by the requireAuthentication middleware, which accepts any valid access token. Unlike MFA factor enrollment, no AAL2, recent re-authentication, or password confirmation is required before binding a new WebAuthn credential. An attacker who has stolen a victim's bearer JWT (via XSS, malware, or leaked logs) can complete the registration ceremony with their own authenticator. Because passkeys serve as a primary sign-in method, the attacker retains access even after the victim rotates their password and revokes all sessions.",
  "discovered_at": "2026-05-10T00:00:00+00:00",
  "location": "internal/api/passkey_registration.go:107",
  "poc_sha256": null,
  "preimage_version": 1,
  "project": "supabase/auth",
  "reproduction": [
    "Attacker steals the victim's bearer JWT (e.g., via XSS on the operator's frontend).",
    "Attacker calls POST /passkeys/registration/begin with the stolen token and receives WebAuthn creation options.",
    "Attacker completes the WebAuthn ceremony with their own hardware key and POSTs to /passkeys/registration/finish.",
    "Server stores the attacker's credential against the victim's user record.",
    "Victim later changes password and revokes all sessions; attacker still signs in via /passkeys/authentication using the planted credential."
  ],
  "technical_details": "The registration endpoints are gated only by requireAuthentication (any valid access token) rather than a step-up check. There is no enforcement of AAL2, fresh re-authentication, or proof of an existing credential before a new WebAuthn authenticator is bound to the user, so possession of a session token alone is sufficient to add a persistent primary login credential.",
  "title": "Passkey registration requires no step-up authentication",
  "vendor_severity": null
}