MFA testing checklist for QA teams
Multi-factor auth is where security bugs and usability bugs meet. Most teams test that the happy path works and stop. Here's the full checklist — including the bypass and lockout cases that actually matter.
part ofSecurity testing for QAMFA testing has a trap: the happy path is easy and the dangerous cases are quiet. Entering a valid code and getting in proves almost nothing — the bugs live in what happens with wrong codes, old codes, reused codes, and in whether the second factor can be skipped entirely. This checklist walks the whole surface, building on session expiry and authentication testing.
The bypass cases — test these first
The worst MFA bug is one that lets you skip the second factor. These are the checks that justify the whole effort:
- Can you reach a post-login page directly? After entering the password but before the MFA step, try navigating straight to a logged-in URL. If it loads, MFA is decorative — the session was already authenticated.
- Does the API enforce it, or just the UI? Hit the authenticated API endpoints with the half-authenticated session token. The server must reject everything until the second factor is verified.
- Can you change the response? Some broken implementations send the code's validity to the client. Watch the verify call — if a
falsecan be flipped totruein the response, or the redirect happens regardless, the check is on the wrong side.
The code-handling cases
Once you know the factor can't be skipped, test the code itself like any other input with security weight:
- Wrong code is rejected with a generic error (not "code expired" vs "code wrong" — don't leak which).
- Expired code is rejected — generate one, wait past the validity window, try it.
- Reused code is rejected — a one-time code must be exactly one-time, even within its validity window.
- Rate limiting / lockout kicks in after a handful of wrong attempts. A 6-digit code is a million guesses; without a lockout, that's brute-forceable. This is the single most-skipped MFA test.
- Code for the right account — confirm a code issued to user A can't verify user B's login.
The recovery and lifecycle cases
MFA bugs cluster around the edges — enrolment, backup, and disabling — because that's where the "what if the user lost their phone?" logic lives, and recovery paths are notorious for being a backdoor around the factor you just secured:
MFA testing checklist
- Bypass: can't reach authenticated pages or APIs before the second factor is verified
- Wrong / expired / reused code: all rejected; reuse blocked even inside the validity window
- Brute force: lockout or rate limit after N wrong attempts (this is the big one)
- Cross-account: a code for one user can't authenticate another
- Enrolment: enabling MFA requires re-auth; the secret/QR isn't exposed in logs or responses
- Backup codes: single-use, can't be reused, regenerate invalidates the old set
- Recovery flow: "lost device" path can't silently disable MFA without strong verification
- Disabling MFA: requires the current factor or a password, not just an active session
- Remember-this-device: scoped, expires, and is revoked on logout / password change
- Session after MFA: a fresh, fully-authenticated session is issued; the pre-MFA token is now useless
A note on usability
MFA is also where real users get locked out, so test the human side too: is the error message clear when a code is wrong? Is there a visible "resend code" with its own rate limit? Does the code field handle a pasted code, autofill, and the leading-zero case? A factor so frustrating that users disable it is a security problem of a different kind. Security and usability aren't opposites here — the goal is an MFA flow that's hard for an attacker and easy for the legitimate user.
// RELATED QA.CODES RESOURCES
Checklist
Glossary
// related
The 12 API bugs I check for first
A high-value checklist: the twelve API bugs that surface most often, from wrong status codes to idempotency failures.
My practical accessibility smoke test before release
A ten-minute accessibility pass any QA can run before release — keyboard, focus, contrast, and the obvious screen-reader checks.