SecureBlockLog inStart a pentest
Vulnerability Repository
HighAuthentication

Multi-Factor Authentication Bypass

Logic flaws, code reuse, rate limit absence, and response manipulation allow attackers to skip or circumvent MFA challenges and authenticate with credentials alone.

CVSS 8.8CWE CWE-287OWASP A07:2021 — Identification and Authentication Failures

Description

Multi-factor authentication bypass (CWE-287) encompasses a class of vulnerabilities where the implementation of a second authentication factor can be circumvented, skipped, or defeated — rendering MFA protection ineffective even when users have properly enrolled. As MFA adoption has increased, attackers and penetration testers have shifted focus from credential theft to MFA bypass, making this one of the most critical authentication vulnerability categories.

Common bypass techniques include: direct endpoint access (skipping the MFA challenge by accessing the authenticated resource directly after password verification); response manipulation (changing the MFA verification response from false to true in an HTTP intercepting proxy); code brute force (6-digit TOTP codes have only 1 million possibilities — rate-limit absence makes them brute-forceable); code reuse (using an already-used TOTP code before its window expires); backup code weakness (predictable or high-quantity backup codes); and account recovery bypass (using password reset or account recovery flows to circumvent MFA entirely).

This vulnerability class falls under OWASP A07:2021 (Identification and Authentication Failures) and is high severity because it invalidates one of the most important security controls deployed to protect against credential compromise. A bypassed MFA offers no additional protection over password-only authentication.

How It Works

Direct endpoint bypass — the most common finding:

# Normal flow:
POST /login → 200 OK (password accepted, MFA required, intermediate session)
POST /verify-mfa → 200 OK → Authenticated session

# Bypass:
POST /login → 200 OK (intermediate session token set)
GET /dashboard → Try accessing authenticated resource directly
# If the server only checks for any session token (not MFA completion),
# the intermediate session may be accepted as authenticated

Response manipulation with Burp Suite:

POST /verify-mfa
{"code": "123456"}

Response (intercepted):
{"success": false, "message": "Invalid code"}

→ Intercept and modify to:
{"success": true, "message": ""}

→ Application forwards to dashboard — MFA bypassed

Note: this works only if the client-side response drives the flow, not a server-side session state change. But a surprising number of implementations make this mistake.

TOTP brute force (no rate limiting):

# 6-digit TOTP: 000000–999999
# Without rate limiting, testable in minutes
for code in range(0, 1000000):
    r = requests.post('/verify-mfa', json={'code': f'{code:06d}'})
    if r.status_code == 200 and 'dashboard' in r.url:
        print(f'Valid code: {code:06d}')
        break

With TOTP's 30-second window and three valid codes at a time (±1 window), the attack space is manageable without any rate limiting.

Account recovery bypass:

1. Attacker has stolen credentials but not the MFA device
2. Attacker clicks "Can't access your authenticator?"
3. Recovery flow asks for email verification only
4. Attacker receives email at the compromised email address
5. MFA is bypassed via account recovery — no second factor required

Impact

  • Complete MFA Invalidation — Rendering the second factor ineffective, reducing security to password-only authentication
  • Privileged Account Takeover — Admin accounts protected by MFA are particularly targeted; bypass compromises the highest-privilege accounts
  • Credential Breach Exploitation — Enabling attackers with stolen password databases to successfully compromise accounts that added MFA specifically to defend against credential breaches
  • Mass Account Compromise — Rate-limit absence on TOTP codes enables automated brute force across thousands of accounts

Detection

  1. Test direct endpoint access — after successfully entering a correct password, skip the MFA step and directly request an authenticated endpoint (/dashboard, /api/profile). Check whether the intermediate session (post-password, pre-MFA) is accepted.
  2. Test response manipulation — intercept the MFA verification response with Burp Suite. Change "success": false to "success": true and observe whether the application grants access.
  3. Test TOTP brute force — verify whether rate limiting is applied to the TOTP submission endpoint. Submit 10+ invalid codes rapidly and check for lockout, CAPTCHA, or rate limiting.
  4. Test code reuse — use a valid TOTP code immediately after it has been successfully used. It should be rejected; if not, code reuse is possible.
  5. Test backup code quantity and predictability — examine backup codes provided during enrollment. Are they random? How many are provided? Can they be regenerated indefinitely?
  6. Test account recovery flows — walk through the "lost MFA device" recovery flow. Determine whether it can be completed using only email access (without the second factor).

Remediation

Enforce MFA completion server-side. Use a distinct session state (e.g., mfa_required, mfa_complete) stored server-side. Protect all authenticated endpoints by checking that the session is in mfa_complete state, not just that a session exists.

Never trust client-side MFA verification responses. The server must set the authenticated session state directly after verifying the MFA code server-side. Client-side response values must not control authentication decisions.

Apply rate limiting and lockout to MFA endpoints. Lock or delay after 5-10 failed TOTP attempts. Implement exponential backoff and alert the user on repeated failures:

@limiter.limit("5 per 10 minutes")
def verify_mfa():
    code = request.json.get('code')
    if not totp.verify(code):
        increment_failure_count(user_id)
        return jsonify(success=False), 401
    session['mfa_complete'] = True
    return jsonify(success=True)

Mark TOTP codes as used. Store used codes in a cache (Redis) within the validity window to prevent reuse.

Require strong account recovery. Recovery from lost MFA should require pre-registered offline recovery codes, not just email verification.

Ready when you are
Scope a pentest in the next two minutes.
Start scoping