2FA/MFA/OTP Bypass
Tip
Learn & practice AWS Hacking:
HackTricks Training AWS Red Team Expert (ARTE)
Learn & practice GCP Hacking:HackTricks Training GCP Red Team Expert (GRTE)
Learn & practice Az Hacking:HackTricks Training Azure Red Team Expert (AzRTE)
Browse the full HackTricks Training catalog.Support HackTricks
- Check the subscription plans!
- Join the 💬 Discord group, the telegram group, follow @hacktricks_live on X/Twitter, or check the LinkedIn page and YouTube channel.
- Share hacking tricks by submitting PRs to the HackTricks and HackTricks Cloud github repos.
Enhanced Two-Factor Authentication Bypass Techniques
Direct Endpoint Access
See Proxmox VE for a product-specific example of client-selected TFA state.
Try the post-login endpoint directly and verify that the server—not only the UI—requires completion of the MFA state. If an application incorrectly trusts navigation metadata, also test the correctly spelled HTTP Referer header; a secure implementation must not use it as proof of MFA.[2][5]
Token Reuse
Reutilizing previously used tokens for authentication within an account can be effective.[2]
Utilization of Unused Tokens
Test whether an unused token generated for your own test account is incorrectly accepted for another authorized test account. This checks that OTPs are bound to the correct account, session, purpose, and transaction.[2][5]
Exposure of Token
Investigate whether the token is disclosed in a response from the web application.[2]
Verification Link Exploitation
Using the email verification link sent upon account creation can allow profile access without 2FA, as highlighted in a detailed post.[3]
Session Manipulation
Initiate sessions for two authorized test accounts, complete MFA in one, and verify that its completion state cannot be transplanted into the other session. The backend must bind the MFA result to the same account and pre-authentication session.[5]
Password Reset Mechanism
Investigating the password reset function, which logs a user into the application post-reset, for its potential to allow multiple resets using the same link is crucial. Logging in with the newly reset credentials might bypass 2FA.[2]
OAuth Platform Compromise
Check whether a federated OAuth/OIDC login path enforces an assurance level equivalent to the application’s password-plus-MFA path. Control of the upstream identity account may bypass the application’s local MFA only when the relying party accepts that weaker federated session.[5]
Brute Force Attacks
Rate Limit Absence
The lack of a limit on the number of code attempts allows for brute force attacks, though potential silent rate limiting should be considered.[1][2]
Note that even if a rate limit is in place you should try to see if the response is different when the valid OTP is sent. In this post, the bug hunter discovered that even if a rate limit is triggered after 20 unsuccessful attempts by responding with 401, if the valid one was sent a 200 response was received.[4]
Slow Brute Force
A slow brute force attack is viable where flow rate limits exist without an overarching rate limit.[1]
Code Resend Limit Reset
Resending the code resets the rate limit, facilitating continued brute force attempts.[1]
Client-Side Rate Limit Circumvention
If throttling exists only in JavaScript, replay the request directly and verify whether the server independently enforces per-account, per-session, and broader abuse limits.[1][5]
Internal Actions Lack Rate Limit
Rate limits may protect login attempts but not internal account actions.[1]
SMS Code Resend Costs
Excessive resending of codes via SMS incurs costs to the company, though it does not bypass 2FA.
Infinite OTP Regeneration
Endless OTP generation with simple codes allows brute force by retrying a small set of codes.[1]
Race Condition Exploitation
Send the same OTP or recovery code concurrently and verify that validation and consumption are atomic. A race exists if more than one request can redeem a single-use value.[5]
CSRF/Clickjacking Vulnerabilities
Exploring CSRF or Clickjacking vulnerabilities to disable 2FA is a viable strategy.[1][2]
“Remember Me” Feature Exploits
Predictable Cookie Values
Guessing the “remember me” cookie value can bypass restrictions.[1]
IP Address Impersonation
Impersonating the victim’s IP address through the X-Forwarded-For header can bypass restrictions.[1]
Utilizing Older Versions
Subdomains
Test whether subdomains expose older applications or authentication paths that lack the current MFA requirement.[1]
API Endpoints
Older API versions, indicated by /v*/ directory paths, may be vulnerable to 2FA bypass methods.[1]
Handling of Previous Sessions
Terminating existing sessions upon 2FA activation secures accounts against unauthorized access from compromised sessions.[1]
Access Control Flaws with Backup Codes
Immediate generation and potential unauthorized retrieval of backup codes upon 2FA activation, especially with CORS misconfigurations/XSS vulnerabilities, poses a risk.[1][2]
Information Disclosure on 2FA Page
Sensitive information disclosure (e.g., phone number) on the 2FA verification page is a concern.[1]
Password Reset Disabling 2FA
A process demonstrating a potential bypass method involves account creation, 2FA activation, password reset, and subsequent login without the 2FA requirement.[2]
Decoy Requests
Utilizing decoy requests to obfuscate brute force attempts or mislead rate limiting mechanisms adds another layer to bypass strategies. Crafting such requests requires a nuanced understanding of the application’s security measures and rate limiting behaviours.
OTP Construction errors
If the OTP is derived only from predictable or client-supplied data, a user may be able to reproduce it. Verify that codes are generated from a cryptographically secure secret, are short-lived, single-use, and bound to the correct account and action.[5]
Step-up authentication not enforced (acr, amr, auth_time)
Some apps let users log in with a weak method and only ask for MFA or a fresh login before a sensitive action (changing the email, adding a payee, exporting data, opening an admin area). This is called step-up authentication. With OpenID Connect or OAuth it usually works like this:
- The client asks the identity provider for a stronger login with
acr_values=<level>and/ormax_age=<seconds>in the authorization request.[6] - The ID token, or an access token profile that carries authentication context, can say what happened:
acr(the authentication level satisfied),amr(the methods used, for example["pwd","otp"]) andauth_time(when the user authenticated). These claims are not all present in every token.[6] - An API that needs a stronger login answers
401withWWW-Authenticate: Bearer error="insufficient_user_authentication", acr_values="...", max_age=..., and must checkacrandauth_timein the token it receives.[7]
acr_values is only a request. The client (or the API) must check the claims that come back. OIDC Core says the client should check that the acr value is appropriate and should check auth_time and ask for re-authentication if too much time has passed.[6] If it does not, the step-up can be skipped.
Black-box tests with a test account that has MFA:
- Capture the step-up authorization request and remove
acr_values/max_age, or changeacr_valuesto a weaker value (for example frommfaorurn:...:loa:2to the value seen at normal login). Finish the login without MFA and use the result for the sensitive action. - Call the sensitive endpoint directly with the normal login token or session (low
acr,amrwithoutotp/mfa). It must be rejected with a step-up challenge. - Use a token whose
auth_timeis older than the requiredmax_age(log in, wait, then try the action). - After one successful step-up (for example to view an API key), reuse the same “elevated” session or token for other sensitive actions, and for the same action much later. Check whether the elevated state is scoped to one action and expires.
- If the app keeps the step-up result in a client-side flag (
"mfaVerified": true,elevated=1cookie, a field in a non-signed token), change it manually.
It is vulnerable when the sensitive action succeeds without the stronger acr/amr or with an auth_time older than allowed. For an elevated session flag reused on unrelated functions, also see session-scoped authorization state reuse.
References
- [1] Two-Factor Authentication: Security Testing and Possible Bypasses
- [2] 2 Factor Authentication Bypass
- [3] Behind the Scenes of a Security Bug: The Perils of 2FA Cookie Generation
- [4] The $2,200 ATO Most Bug Hunters Overlooked by Closing Intruder Too Soon
- [5] OWASP Multifactor Authentication Cheat Sheet
- [6] OpenID Connect Core 1.0
- [7] RFC 9470 - OAuth 2.0 Step Up Authentication Challenge Protocol
Tip
Learn & practice AWS Hacking:
HackTricks Training AWS Red Team Expert (ARTE)
Learn & practice GCP Hacking:HackTricks Training GCP Red Team Expert (GRTE)
Learn & practice Az Hacking:HackTricks Training Azure Red Team Expert (AzRTE)
Browse the full HackTricks Training catalog.Support HackTricks
- Check the subscription plans!
- Join the 💬 Discord group, the telegram group, follow @hacktricks_live on X/Twitter, or check the LinkedIn page and YouTube channel.
- Share hacking tricks by submitting PRs to the HackTricks and HackTricks Cloud github repos.


