21 lines
958 B
Markdown
21 lines
958 B
Markdown
# 2FA is NOT a hard stop (2026-08-20 update)
|
|
|
|
The original reference said "2FA is a hard stop — cannot proceed without user." This is FALSE when using Playwright + TOTP + recovery codes.
|
|
|
|
## Proven Bypass Chain
|
|
1. Login with email + password via Playwright
|
|
2. 2FA: generate TOTP from `seed_2fa` → `pyotp.TOTP(seed).now()` → fill `input[name="app_otp"]`
|
|
3. Device verification: click "Use recovery code" → enter first recovery code from list
|
|
4. 2FA checkup page: click "More options" → "Verify your 2FA setup tomorrow"
|
|
5. Continue OAuth flow
|
|
|
|
This works for accounts with:
|
|
- 2FA TOTP seed (base32)
|
|
- Recovery codes (comma-separated list)
|
|
- Both fields present in account JSON
|
|
|
|
The only scenario where 2FA IS a hard stop:
|
|
- No TOTP seed available (only recovery codes, no authenticator app)
|
|
- No recovery codes available (only TOTP, no backup)
|
|
- GitHub flags the account for suspicious activity (rare)
|
|
- SMS-based 2FA (no seed to generate codes from) |