diff --git a/strix/skills/vulnerabilities/mfa_bypass.md b/strix/skills/vulnerabilities/mfa_bypass.md new file mode 100644 index 00000000..8e857f5f --- /dev/null +++ b/strix/skills/vulnerabilities/mfa_bypass.md @@ -0,0 +1,257 @@ +--- +name: mfa-bypass +description: MFA implementation testing covering pre-MFA session access, OTP brute force, recovery flow abuse, enrollment weaknesses, and client-side MFA gate bypasses +--- + +# MFA Bypass + +Multi-factor authentication is a critical security control, but implementations frequently contain bypasses that reduce it to single-factor or no-factor authentication. The gap between password verification and MFA completion, weak OTP enforcement, abusable recovery flows, and client-side MFA gates are all common real-world findings. Test MFA as a system, not just the code entry step. + +## Attack Surface + +**MFA Methods** +- TOTP (Google Authenticator, Authy, etc.) +- SMS/voice OTP +- Email OTP/magic links +- Push notifications (Duo, Microsoft Authenticator) +- Hardware tokens (FIDO2/WebAuthn, YubiKey) +- Backup/recovery codes +- Security questions (weakest — often the bypass itself) + +**Authentication Flow Stages** +``` +[Password] → [Pre-MFA State] → [MFA Challenge] → [Authenticated] + ↓ ↓ ↓ ↓ + Login page Partial session Code entry Full access + API access? Brute force? Complete + Skip possible? Replay? +``` + +**Target Surfaces** +- Web application login flows +- API authentication endpoints +- Mobile app authentication +- SSO/federation flows (SAML, OIDC) +- Admin panels and privileged access +- Account recovery and password reset +- MFA enrollment and management + +## Key Vulnerabilities + +### Pre-MFA Session Access + +The most common MFA bypass. After password verification but before MFA completion, the application issues a session token or cookie that grants partial (or full) API access. + +**Test** +1. Complete password authentication +2. Stop at MFA prompt — do NOT submit the code +3. Inspect cookies/tokens received after password step +4. Use those cookies/tokens to access API endpoints directly + +``` +POST /login {"username":"user","password":"pass"} +Response: Set-Cookie: session=abc123; ... + {"status":"mfa_required","redirect":"/mfa"} + +# Now try accessing protected endpoints with the session cookie +GET /api/profile Cookie: session=abc123 +GET /api/settings Cookie: session=abc123 +GET /api/users Cookie: session=abc123 +``` + +**What to Look For** +- API endpoints accessible with the pre-MFA session +- Different privilege levels between pre-MFA and post-MFA tokens +- JWT claims like `mfa_verified: false` that are checked client-side but not server-side +- GraphQL introspection or data queries working with partial auth + +### OTP Brute Force + +6-digit TOTP has 1,000,000 combinations. Without rate limiting, it's brutable. + +**Rate Limit Testing** +``` +POST /mfa/verify {"code":"000001"} → 403 +POST /mfa/verify {"code":"000002"} → 403 +POST /mfa/verify {"code":"000003"} → 403 +... +# Does the server lock out, throttle, or block after N attempts? +``` + +**Bypass Techniques** +- **No rate limit** — Brute force all 6 digits +- **Per-IP rate limit** — Rotate IPs via proxy +- **Reset on new code** — Wait for TOTP window to rotate (30s), counter resets +- **Race condition** — Send many parallel requests before lockout triggers +- **Response manipulation** — Change `403` to `200` or `mfa_verified: false` to `true` if client-side +- **Null/empty code** — Submit empty string, `null`, `0`, `000000` + +**OTP Window Testing** +``` +# Test if expired TOTP codes are accepted (window too large) +# Generate code at T, wait 60-90 seconds, submit +POST /mfa/verify {"code":""} + +# Test if the same code can be reused (replay) +POST /mfa/verify {"code":"123456"} → 200 (success) +POST /mfa/verify {"code":"123456"} → 200? (should be rejected) +``` + +### Recovery Flow Abuse + +**Backup Code Weaknesses** +- Backup codes not rate-limited separately from TOTP +- Predictable backup code format (sequential, low entropy) +- Backup codes not invalidated after use +- No notification when backup code is used + +**Account Recovery Bypasses MFA** +``` +# Password reset flow +POST /forgot-password {"email":"victim@target.com"} +# Click reset link +POST /reset-password {"token":"reset_token","password":"newpass"} +# Login with new password — is MFA required? Or was it silently disabled? +``` + +**Method Downgrade** +- TOTP configured, but SMS fallback available without restriction +- Push notification → can fall back to email OTP +- Request a different MFA method on the challenge page +- API parameter: `{"mfa_method":"sms"}` to force weaker method + +**Security Question Fallback** +- MFA can be bypassed by answering security questions +- Questions are often guessable or researchable (OSINT) + +### Enrollment Flow Weaknesses + +**Adding New MFA Without Verification** +``` +# Can you add a new TOTP device without verifying the existing one? +POST /settings/mfa/enroll {"method":"totp"} +Response: {"secret":"JBSWY3DPEHPK3PXP","qr_url":"..."} +# Is the current MFA factor required to complete this? +``` + +**Removing MFA** +``` +# Can MFA be disabled without re-authentication? +DELETE /settings/mfa +POST /settings/mfa/disable {"confirm": true} +# Does this require entering a current TOTP code? +``` + +**Enrollment Token Leaks** +- TOTP secret visible in page source, API response, or QR code URL +- Secret transmitted over non-HTTPS channels +- Secret logged in server-side logs or analytics + +### Client-Side MFA Gates + +**JWT/Token Manipulation** +```json +// Decode JWT +{"sub":"user123","mfa_verified":false,"role":"user"} + +// Modify and re-sign (if weak/no signature verification) +{"sub":"user123","mfa_verified":true,"role":"user"} +``` + +**Cookie/Parameter Tampering** +``` +# Check if MFA state is in a cookie +Cookie: mfa_complete=0 +# Change to +Cookie: mfa_complete=1 + +# Check URL parameters +GET /dashboard?mfa_verified=true +``` + +**Response Manipulation** +``` +# Original response to MFA check +{"mfa_required": true, "redirect": "/mfa"} + +# Intercept and change to +{"mfa_required": false, "redirect": "/dashboard"} +# Does the server enforce MFA on subsequent requests? +``` + +### Direct Navigation Bypass + +``` +# After password auth, instead of following redirect to /mfa: +GET /dashboard # Try accessing protected pages directly +GET /api/v1/user/me # Try API endpoints +GET /admin # Try admin pages +``` + +### SSO/Federation MFA Bypass + +**IdP vs SP MFA** +- IdP enforces MFA, but SP accepts the SAML assertion without checking MFA claim +- IdP issues assertion after password-only auth for certain apps +- SP trusts `AuthnContextClassRef` value without IdP actually performing MFA + +**Session Persistence** +- SSO session outlives MFA policy — user authenticates with MFA once, then has a long-lived SSO token +- Re-authentication policy not enforced for sensitive operations + +### API Key/Token Bypass + +- API keys generated before MFA enrollment still work without MFA +- Personal access tokens bypass MFA entirely (by design in some systems — document it) +- OAuth refresh tokens survive MFA policy changes + +## Testing Methodology + +1. **Map the MFA flow** — Document every step from password entry to full authentication; identify session tokens issued at each stage +2. **Pre-MFA access** — Test API access with the session token received after password-only auth +3. **Rate limiting** — Submit 10+ incorrect OTP codes rapidly; check for lockout, throttle, or CAPTCHA +4. **Code validation** — Test expired codes, reused codes, empty/null codes, codes from wrong device +5. **Recovery flows** — Test password reset, backup codes, security questions — do they bypass MFA? +6. **Method downgrade** — If multiple MFA methods available, test switching to the weakest +7. **Enrollment** — Test adding/removing MFA devices without re-verification +8. **Client-side gates** — Inspect JWT claims, cookies, and response bodies for MFA state; tamper and test +9. **Direct navigation** — Skip the MFA page and navigate directly to authenticated pages +10. **SSO integration** — If SSO is used, test whether MFA enforcement is at IdP, SP, or neither + +## Validation + +1. **Pre-MFA access** — Show API responses with sensitive data using only the post-password, pre-MFA session token. Include paired requests: same endpoint with full MFA token vs pre-MFA token +2. **Rate limit absence** — Determine the application's actual lockout threshold (if any) by incrementally increasing failed attempts. Show that the threshold is either absent or set unreasonably high (e.g., >100 attempts). Include timestamps proving no throttle or lockout at the tested volume. Note: 10 failed attempts alone does NOT prove absence of rate limiting if the threshold is set higher — continue testing until you observe either enforcement or reach a brute-forceable volume +3. **Code replay** — Show the same OTP code accepted for **two separate authentication sessions** (not just two requests within the same session). Demonstrate that the replay enables unauthorized access — e.g., an attacker who captured a valid code can use it after the legitimate user has already consumed it. Same-window duplicate verification without a concrete security consequence is not a vulnerability +4. **Recovery bypass** — Show complete password reset flow resulting in login without MFA prompt +5. **Client-side gate** — Show tampered JWT/cookie granting access to protected resources with `mfa_verified=false` → `true` +6. Provide full HTTP request/response pairs for each finding + +## False Positives + +- Pre-MFA session token exists but grants zero API access (server validates MFA completion on every endpoint) +- Rate limiting kicks in after N attempts but error response doesn't change (silent lockout — verify with a correct code after N failures) +- TOTP window accepts T-1 and T+1 codes (30s tolerance is standard and by design per RFC 6238) +- API keys bypass MFA by design and this is documented/intended (still worth noting in report) +- SSO session persistence is configured with appropriate re-auth policies for sensitive operations + +## Impact + +- **Full authentication bypass** — Access authenticated resources without completing MFA, reducing security to single-factor +- **Account takeover** — Brute force OTP or bypass MFA after credential stuffing/phishing +- **Privilege escalation** — Pre-MFA session may have different privilege boundaries than post-MFA +- **Compliance violation** — PCI DSS (8.3), HIPAA, SOC 2, and most frameworks require functional MFA; a bypassable MFA fails audit +- **Lateral movement** — Bypass MFA on admin accounts to access management interfaces + +## Pro Tips + +1. The pre-MFA session test is the highest-yield check — many applications issue a valid session cookie after password auth and rely on a client-side redirect to the MFA page +2. Always test the password reset flow end-to-end — the most common MFA bypass is `forgot password → set new password → login without MFA` +3. Check if MFA state is in the JWT — decode every token the application issues and look for `mfa`, `mfa_verified`, `amr`, `acr` claims +4. For TOTP brute force, the math matters: 6 digits = 10^6 combinations, but TOTP codes rotate every 30 seconds, so you need ~33,333 requests/second to guarantee a hit within one window. Test rate limiting with far fewer requests. +5. Test from the API first — web UIs often have client-side MFA enforcement that the API doesn't +6. WebAuthn/FIDO2 is significantly harder to bypass than TOTP/SMS — note the MFA method in your findings for accurate severity + +## Summary + +MFA bypass testing targets the implementation, not the cryptographic protocol. The most common bypasses are pre-MFA session access (partial auth), absent rate limiting on OTP entry, recovery flows that disable MFA, and client-side MFA gates. Test every transition in the authentication flow independently. A bypassable MFA is worse than no MFA because it creates false confidence.