JWT Attack (JSON Web Token)
A JWT attack exploits vulnerabilities in JSON Web Token implementation to bypass authentication, escalate privileges, or impersonate users. Common attacks include algorithm confusion (setting 'alg': 'none'), weak signature verification, token manipulation, and exploiting token reuse across services. JWTs are widely used in modern APIs and SPAs, making these attacks particularly impactful.
How JWT Attack (JSON Web Token) Works
JWT attacks target the token lifecycle: creation, transmission, verification, and storage. The token structure (header.payload.signature) contains sensitive claims but is often improperly validated. Attackers manipulate tokens to change user roles, extend expiration, forge signatures, or bypass verification entirely. Unlike session cookies managed server-side, JWTs are stateless — once issued, the server must validate them without database lookup, increasing the risk of implementation errors.
Analyze JWT implementation
Identify how tokens are generated, transmitted, and validated. Check for weak secrets (dictionary words, short keys), insecure algorithms (none, HS256 when RS256 expected), missing claim validations (exp, iat, nbf), and token reuse across different security contexts.
Exploit weak verification
If the server doesn't verify the signature properly, attackers can forge tokens. Test by removing the signature entirely (set 'alg': 'none') or by signing with weak or stolen secrets. Some libraries accept tokens without signature verification if the algorithm is explicitly set to 'none'.
Manipulate token claims
If tokens are signed with a weak or known secret, decode and modify claims to elevate privileges. Common targets: 'role' (admin), 'sub' (user ID), 'exp' (expiration), or custom claims that control access. Re-sign with the compromised secret and submit to the application.
Exploit algorithm confusion
Some JWT libraries allow the attacker to specify the signing algorithm. Attackers change 'alg' from RS256 (public key) to HS256 (symmetric), tricking the server into using the public key as the symmetric signing key. This allows token forgery without the private key.
Real-World Examples
Critical vulnerability in popular JWT libraries
Security researchers discovered algorithm confusion vulnerabilities in multiple JWT libraries across different languages. The vulnerability allowed attackers to bypass signature verification by changing the algorithm header from RS256 to HS256. This affected thousands of applications, including enterprise systems and financial platforms using vulnerable library versions.
SaaS platform privilege escalation via weak JWT secret
A SaaS platform used a default weak JWT secret for development that was accidentally deployed to production. Attackers discovered the secret through exposed environment variables, generated admin tokens, and gained access to all customer data. The breach exposed over 50,000 user records and resulted in a $2.3 million fine under GDPR.
JWT none algorithm bypass in microservices architecture
A company's microservices architecture used JWT for inter-service authentication. Due to a misconfiguration, the verification service accepted tokens with 'alg': 'none', allowing attackers to bypass authentication entirely. Attackers accessed internal APIs, exfiltrated customer data, and disrupted service for 4 hours before detection.
Impact & Risk Assessment
JWT attacks enable complete account takeover, privilege escalation to administrative access, and unauthorized access to protected APIs. In stateless architectures, compromised tokens are difficult to revoke quickly. Attackers can access multiple systems if tokens are reused across services. Impact includes data breaches, financial fraud, service disruption, and compliance violations (GDPR, HIPAA, PCI DSS). Stateful systems with session management can invalidate sessions instantly; JWT-based systems require token blocklists or short expiration periods, increasing complexity and potential for errors.
How to Detect JWT Attack (JSON Web Token)
Monitor for suspicious JWT-related patterns: tokens with 'alg': 'none', unusually long or short tokens, tokens with invalid signatures, expired tokens being accepted, or claims mismatching expected formats. Log all JWT verification failures with full token metadata (excluding secrets). Implement anomaly detection on claim values (unexpected role changes, impossible expiration dates). Use static analysis to detect vulnerable JWT libraries or unsafe verification patterns in code. Monitor for token reuse across different IP addresses or user agents indicating token theft.
How to Prevent JWT Attack (JSON Web Token)
Use strong, cryptographically random secrets (minimum 256 bits for HS256, 2048+ bits for RSA). Never use the 'none' algorithm in production. Always verify the signature before using any claims. Validate all critical claims: expiration (exp), not-before (nbf), issued-at (iat), issuer (iss), audience (aud), and subject (sub). Use versioning for token schemas to detect incompatible changes. Implement short token lifetimes (15-30 minutes for access tokens) with refresh tokens stored securely. Use token rotation to mitigate token reuse. Implement proper algorithm whitelisting in verification libraries. Regularly audit dependencies for known JWT vulnerabilities. Consider stateful JWT (adding jti claim and maintaining server-side blocklist) for critical operations.
Code Examples
import jwt
# VULNERABLE: Weak secret and accepts any algorithm
SECRET = 'my-secret-key' # Dictionary word, weak!
def create_token(user_id, role):
return jwt.encode(
{'user_id': user_id, 'role': role},
SECRET,
algorithm='HS256'
)
def verify_token(token):
try:
return jwt.decode(token, SECRET, algorithms=['HS256', 'none'])
# ^ Accepts 'none' algorithm - vulnerable!
except jwt.InvalidTokenError:
return None
# Attacker can forge token by changing alg to 'none'
# and modifying role to 'admin'
import jwt
from datetime import datetime, timedelta
import os
# SECURE: Strong secret from environment
SECRET = os.getenv('JWT_SECRET')
if not SECRET or len(SECRET) < 32:
raise ValueError('JWT_SECRET must be at least 32 characters')
def create_token(user_id, role):
payload = {
'user_id': user_id,
'role': role,
'iat': datetime.utcnow(),
'exp': datetime.utcnow() + timedelta(minutes=15), # Short-lived
'iss': 'myapp.com', # Issuer validation
'aud': 'myapp-api' # Audience validation
}
return jwt.encode(payload, SECRET, algorithm='HS256')
def verify_token(token):
try:
payload = jwt.decode(
token,
SECRET,
algorithms=['HS256'], # Only accept HS256
issuer='myapp.com',
audience='myapp-api',
options={'require': ['exp', 'iat', 'iss', 'aud']}
)
# Additional business logic validation
if payload.get('role') not in ['user', 'admin']:
raise jwt.InvalidTokenError('Invalid role')
return payload
except jwt.ExpiredSignatureError:
raise ValueError('Token has expired')
except jwt.InvalidTokenError as e:
raise ValueError(f'Invalid token: {str(e)}')
const jwt = require('jsonwebtoken');
const crypto = require('crypto');
const JWT_SECRET = process.env.JWT_SECRET;
const TOKEN_VERSION = 'v1';
// Token blocklist (in production, use Redis)
const tokenBlocklist = new Set();
function createAccessToken(userId, role) {
return jwt.sign(
{
userId,
role,
version: TOKEN_VERSION,
type: 'access'
},
JWT_SECRET,
{
algorithm: 'HS256',
expiresIn: '15m',
issuer: 'myapp.com',
audience: 'myapp-api',
subject: userId.toString()
}
);
}
function createRefreshToken(userId) {
return jwt.sign(
{ userId, version: TOKEN_VERSION, type: 'refresh' },
JWT_SECRET,
{ algorithm: 'HS256', expiresIn: '7d' }
);
}
function verifyToken(token, expectedType = 'access') {
try {
const decoded = jwt.verify(token, JWT_SECRET, {
algorithms: ['HS256'],
issuer: 'myapp.com',
audience: 'myapp-api'
});
// Check if token is in blocklist
const jti = decoded.jti;
if (tokenBlocklist.has(jti)) {
throw new Error('Token has been revoked');
}
// Validate token type
if (decoded.type !== expectedType) {
throw new Error('Invalid token type');
}
// Check version for rotation
if (decoded.version !== TOKEN_VERSION) {
throw new Error('Token version outdated');
}
return decoded;
} catch (error) {
throw new Error(`Token verification failed: ${error.message}`);
}
}
// Revoke a token (e.g., on logout)
function revokeToken(token) {
const decoded = jwt.decode(token);
tokenBlocklist.add(decoded.jti);
}
Strengthen your defenses against JWT Attack (JSON Web Token) with PowerWAF.
Comprehensive web application security with WAF, rate limiting, and real-time threat monitoring.
Free plan spots are limited