How to Test Two-Factor Authentication (2FA) Flow
2FA adds a second factor (something you have) to the password (something you know). It raises security significantly — also the likelihood of user friction. Testing 2FA well covers enrollment, authent
2FA adds a second factor (something you have) to the password (something you know). It raises security significantly — also the likelihood of user friction. Testing 2FA well covers enrollment, authentication, recovery, and backwards compatibility. This guide is the matrix.
Types of 2FA
- TOTP (authenticator app) — Google Authenticator, Authy, 1Password
- SMS — one-time code via text
- Email — code via email
- Push — approval on another device (Google prompts)
- Hardware key — YubiKey, FIDO2 / WebAuthn
- Backup codes — recovery if primary lost
Enrollment
TOTP
- User sees QR code + manual entry string
- User scans QR with authenticator app
- User enters first code to confirm enrollment
- Backup codes generated and shown / downloadable
- Option to re-generate backup codes anytime
SMS / email
- User enters phone / confirms email
- Verification code sent
- User enters code to confirm enrollment
Hardware key
- Browser/app prompts for key insertion
- User taps key to register
- Key associated with account (public key registered)
Authentication
TOTP
- After password, prompt for 6-digit code
- Code accepted within 30s of generation
- Clock skew tolerated (±30s / 1 period)
- Wrong code → error, retry allowed
- Rate limit on retries (prevent brute force)
SMS / email
- Code sent on login
- Code valid 5-10 minutes
- Resend option
- Rate limit
Push
- Prompt on enrolled device
- Approve / deny
- Denial blocks login
- Timeout (often 60s)
- Expiration message clear
Hardware key
- Tap key on browser/app prompt
- Key responds quickly (<1s)
- Wrong key → rejected
- Cross-device (use key on phone for web login)
Recovery
Lost device / phone
- Recovery code flow: user enters backup code
- Backup code uses consume one code
- Backup codes can regenerate after use
- Account recovery via email / SMS as fallback
- Identity verification for high-security accounts (ID upload)
Device reset
- After factory reset, TOTP gone; user uses backup or recovery flow
- Can disable 2FA with both factors (password + 2FA code)
Edge cases
- Clock skew >30 seconds → code rejected; message clear
- Multiple devices enrolled (user can have authenticator on phone + tablet)
- Enrollment while logged in on another device → session preserved or invalidated per policy
- SMS delivery failure → clear message, alternative flow
- Email delivery delay → user waits, retries
- Push notification missed / ignored → login times out
- Hardware key broken → user falls back to backup
- User on airplane mode during TOTP lookup → no internet needed for TOTP (local secret)
- Travel to different timezone → TOTP still works (uses absolute time)
Security
- 2FA secret (TOTP) encrypted at rest
- Secret never shown after enrollment
- Backup codes hashed server-side (like passwords)
- Rate limit on 2FA attempts
- Too many wrong attempts → account lock
- Attempt log visible to user ("3 failed 2FA attempts from Chicago")
- 2FA bypass via "trusted device" option, if offered, works correctly
- Hardware key FIDO2 supported (passwordless potential)
Usability
- Code input auto-focuses next digit (for 6-digit code)
- Paste code from SMS works (auto-fill)
- Paste split-up SMS ("Your code is 123456") extracts digits
- Keyboard is numeric for code entry
- Clear countdown until code expires
- Resend button enables after timer expires
Accessibility
- Code input accessible (keyboard, screen reader)
- Error state announced
- QR code has manual-entry alternative
- Backup codes copyable / downloadable
Admin / account management
- User can view enrolled methods
- User can disable 2FA (with password confirmation)
- User can change enrolled methods
- Admin-forced 2FA for organization
- 2FA-required feature gates (e.g., financial actions require 2FA re-verification)
Testing approach
Manual
- Full enrollment, authentication, recovery cycle
- Lost device scenario (with backup codes)
- Clock skew test (set device time ±5 minutes)
- Multi-device (TOTP on two authenticators)
- All methods (TOTP, SMS, email, push, key)
- Edge cases (airplane mode, expired code, rapid retries)
Automated
- TOTP via
pyotpin tests - Backend: validate secret rotation, secret invalidation
- End-to-end with test authenticator
import pyotp
def test_login_2fa(page, totp_secret):
# login with password
page.fill("#password", "correct-horse")
page.click("text=Login")
# prompt for code
code = pyotp.TOTP(totp_secret).now()
page.fill("#totp", code)
page.click("text=Verify")
expect(page.locator("#home")).to_be_visible()
How SUSA handles 2FA
SUSA accepts TOTP secret at run time and generates codes via pyotp:
susatest-agent test myapp.apk --username test@example.com --password ... --totp-secret JBSWY3DPEHPK3PXP
The adversarial persona stresses the retry limits and attempts bypass.
Common production bugs
- Backup codes displayed but not regenerable — user cannot rotate if compromised
- Rate limit too strict — honest user locked out from typos
- Rate limit too lenient — brute-force viable
- 2FA code valid for minutes, not 30 seconds — replay window
- Push notification delay > timeout — user cannot approve in time
2FA is high-stakes UX. Test every flow, every method, every fallback. Users who fail here lose account access.
Test Your App Autonomously
Upload your APK or URL. SUSA explores like 10 real users — finds bugs, accessibility violations, and security issues. No scripts.
Try SUSA Free