Auth Bypass with Jwt Tokens
How Auth Bypass Manifests in Jwt Tokens
Auth bypass in JWT tokens exploits the stateless nature of JSON Web Tokens, where verification logic failures can grant unauthorized access. The most common pattern involves signature verification bypass through algorithm confusion attacks. When a JWT library accepts 'none' as a valid algorithm, attackers can modify token contents and remove the signature entirely:
// Vulnerable implementation
const token = jwt.sign({ userId: 1 }, 'secret', { algorithm: 'HS256' });
// Attacker modifies to use 'none' algorithm
const tampered = token.split('.')[0] + '.' + token.split('.')[1] + '.signature';
// Server verifies with 'none' algorithm - bypass successful
Another critical vulnerability occurs when applications don't validate the 'kid' (key ID) header parameter properly. Attackers can manipulate the 'kid' to reference arbitrary keys or perform path traversal:
// Malicious token with path traversal in kid
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCIsImtpZCI6"../../config/private.pem"}
Weak secret keys enable brute-force attacks where attackers guess the signing key. A 16-character alphanumeric secret can be cracked in hours using modern hardware. Key confusion attacks occur when servers accept tokens signed with different algorithms than expected - an RSA-signed token might be verified using a public key as if it were an HMAC secret.
Time-based bypasses exploit clock skew between servers. If verification allows excessive clock skew (default often 60 seconds), attackers can use expired tokens during network delays or server synchronization issues. Some implementations also fail to validate the 'nbf' (not before) claim, allowing tokens to be used before their intended activation time.
JWT-Specific Detection
Detecting JWT auth bypass requires examining both token structure and verification implementation. Start by decoding tokens without validation to inspect claims and headers:
import jwt
# Decode without verification to inspect contents
def inspect_jwt(token):
try:
header, payload, signature = token.split('.')
header_data = jwt.decode(header, options={'verify_signature': False})
payload_data = jwt.decode(payload, options={'verify_signature': False})
return header_data, payload_data
except jwt.DecodeError:
return None
Automated scanning tools should verify algorithm validation by testing with 'none' algorithm and mismatched signing methods. Check for weak secrets using password strength analysis on the signing key. Test key ID parameter handling by injecting path traversal sequences and invalid key references.
Clock skew vulnerabilities manifest when tokens remain valid beyond their 'exp' claim by more than 30 seconds. Verify that servers reject tokens with future 'nbf' claims unless within acceptable time windows. Missing or weak audience ('aud') and issuer ('iss') claim validation allows tokens issued for one service to be used on another.
// Security scan checks
const vulnerabilities = [
{ test: 'none_algorithm', description: 'Accepts none algorithm' },
{ test: 'weak_secret', description: 'Uses predictable signing key' },
{ test: 'kid_injection', description: 'Vulnerable to path traversal in kid' },
{ test: 'clock_skew', description: 'Excessive clock skew tolerance' },
{ test: 'missing_claims', description: 'No aud/iss validation' }
];
middleBrick's JWT-specific scanning tests all these vectors automatically, including active exploitation attempts to confirm bypass feasibility. The scanner verifies that tokens cannot be modified without invalidating the signature and that all security claims are properly enforced.
JWT-Specific Remediation
Fix JWT auth bypass by implementing strict verification with constant-time comparison and secure key management. Always specify the expected algorithm explicitly:
// Secure JWT verification
const secretKey = process.env.JWT_SECRET; // 256+ bit random key
const publicKey = fs.readFileSync('public.pem');
function verifyToken(token) {
try {
const decoded = jwt.verify(token, secretKey, {
algorithms: ['HS256'], // Only allow expected algorithm
audience: 'your-audience', // Validate audience
issuer: 'your-issuer' // Validate issuer
});
return decoded;
} catch (error) {
if (error instanceof jwt.JsonWebTokenError ||
error instanceof jwt.TokenExpiredError ||
error instanceof jwt.NotBeforeError) {
throw new Error('Invalid or expired token');
}
throw error;
}
}
Store secrets in environment variables or secret management services, never in code repositories. Use minimum 256-bit keys for HMAC and ensure RSA keys are at least 2048 bits. Implement key rotation strategies with overlapping validity periods.
# Generate secure keys
# HMAC
openssl rand -base64 32
# RSA 2048-bit
openssl genrsa -out private.pem 2048
openssl rsa -in private.pem -pubout -out public.pem
Validate all standard claims: 'exp' must be checked with no clock skew beyond 30 seconds, 'nbf' must be respected, 'aud' must match expected audience, and 'iss' must match trusted issuers. Never trust the 'kid' header without validation - use a whitelist of allowed keys or implement secure key lookup.
// Complete secure middleware
function authMiddleware(req, res, next) {
const authHeader = req.headers.authorization;
if (!authHeader || !authHeader.startsWith('Bearer ')) {
return res.status(401).json({ error: 'Missing token' });
}
const token = authHeader.substring(7);
try {
const decoded = verifyToken(token);
req.user = decoded;
next();
} catch (error) {
console.error('JWT verification failed:', error.message);
res.status(401).json({ error: 'Invalid token' });
}
}
Test your implementation with tools like jwt.io debugger, but never use it for production verification. Implement comprehensive logging for verification failures to detect attack patterns. Regularly audit your JWT implementation against the latest security advisories and update libraries when vulnerabilities are discovered.
Related CWEs: authentication
| CWE ID | Name | Severity |
|---|---|---|
| CWE-287 | Improper Authentication | CRITICAL |
| CWE-306 | Missing Authentication for Critical Function | CRITICAL |
| CWE-307 | Brute Force | HIGH |
| CWE-308 | Single-Factor Authentication | MEDIUM |
| CWE-309 | Use of Password System for Primary Authentication | MEDIUM |
| CWE-347 | Improper Verification of Cryptographic Signature | HIGH |
| CWE-384 | Session Fixation | HIGH |
| CWE-521 | Weak Password Requirements | MEDIUM |
| CWE-613 | Insufficient Session Expiration | MEDIUM |
| CWE-640 | Weak Password Recovery | HIGH |