FIDO2 / WebAuthn / Passkeys Attacks¶
TL;DR¶
FIDO2/WebAuthn is "phishing-resistant" but not invulnerable: - Authentication can be downgraded to phishable methods - Session tokens post-auth are not protected - Server implementations can have bugs - BitM + XSS can bypass even hardware keys
Attack 1: Authentication Downgrade¶
Presented at OutOfTheBox 2025 Bangkok (IOActive)
Concept¶
Force user to use weaker MFA (push notification, OTP) even if FIDO2 is configured.
Technique: JSON Configuration Manipulation¶
Server sends auth methods config:
[
{"authMethodId":"FidoKey", "isDefault":true},
{"authMethodId":"PhoneAppNotification", "isDefault":false}
]
Proxy modifies in transit:
// Disable FIDO2 as default
content = content.replace(
/(\"authMethodId\":\"FidoKey\"[^}]*\"isDefault\":)true/g,
'$1false'
);
// Force Push Notification
content = content.replace(
/(\"authMethodId\":\"PhoneAppNotification\"[^}]*\"isDefault\":)false/g,
'$1true'
);
Technique: CSS Injection¶
Hide FIDO2 option completely:
Impact: Bypasses $500K+ hardware key investment. Logs show legitimate auth.
Attack 2: Session Hijacking Post-Auth¶
Silverfort Research 2024
The Problem¶
FIDO2 protects authentication, not session tokens.
Affected¶
- Microsoft Entra ID: OIDC/SAML tokens valid 1h, refresh tokens for long sessions
- Yubico Playground: Session cookie without device validation
- PingFederate: MITM possible if RP doesn't validate tokens
Solution: Token Binding¶
Binds token to TLS handshake. Only Edge supports it. Chrome removed it.
Microsoft launched Token Protection (preview) — TPM variant.
Attack 3: BitM+ (Browser in the Middle + XSS)¶
Paper 2025: "Defeating FIDO2 with BitM and XSS"
Flow¶
- Victim clicks malicious link
- XSS executes, establishes BitM channel
- Attacker controls victim's browser
- FIDO2 auth happens in legitimate context (correct origin)
- Attacker captures session post-auth
Why It Works¶
FIDO2 verifies origin → victim's browser IS on correct origin. Key signs normally.
Attack 4: Server Implementation Flaws¶
CVE-2025-26788 — StrongKey FIDO Server¶
Affected: SKFS 4.10.0 → 4.15.0
Server doesn't distinguish discoverable vs non-discoverable credentials:
- Attacker starts auth with
victimusername - Server returns victim's credential ID
- Attacker modifies response → swaps in attacker's credential ID
- Attacker authenticates with own passkey
- Server accepts →
victimsession created
POST /basicdemo/fido2/preauthenticate
{"username": "victim"}
# Response contains victim's credential ID
# Attacker swaps to attacker's credential ID
# Auth succeeds as victim
Fix: Update to SKFS 4.15.1
Checklist¶
- Mixed-mode auth enabled? (FIDO2 + push/OTP)
- Session tokens bound to device?
- Token binding supported?
- Conditional Access enforces FIDO2-only?
- Server validates credential ownership?
- XSS on target? (enables BitM+)
Endpoints to Test¶
Mitigations (for defenders)¶
- FIDO2-only policy — no fallback to push/OTP
- Conditional Access — enforce by group/role
- Token Binding if available
- Monitor auth method changes
- Validate credential ID belongs to requested user