JWT Signature is not Verified
Description
The application accepts JSON Web Tokens (JWTs) without properly validating their cryptographic signatures. JWTs are designed to be tamper-proof through digital signatures that ensure the token's integrity. When signature verification is disabled or improperly implemented, attackers can modify the token payload arbitrarily while the application continues to trust the token as authentic. This allows attackers to alter claims within the JWT, such as user identifiers, roles, permissions, or expiration times, effectively bypassing the security controls that JWTs are meant to provide.
Remediation
Implement proper JWT signature verification in all authentication and authorization code paths. Follow these steps:
1. Enable signature verification: Ensure that your JWT library is configured to validate signatures and never accept tokens with invalid or missing signatures.
2. Use strong signing algorithms: Use RS256 (RSA with SHA-256) or ES256 (ECDSA with SHA-256) for asymmetric signing, or HS256 (HMAC with SHA-256) with a strong secret key for symmetric signing. Avoid using the 'none' algorithm.
3. Validate the algorithm: Explicitly specify allowed algorithms and reject tokens using unexpected algorithms to prevent algorithm confusion attacks.
4. Secure key management: Store signing keys securely using environment variables, key management services, or hardware security modules. Never hardcode keys in source code.
Example implementation (Node.js with jsonwebtoken library):
const jwt = require('jsonwebtoken');
const SECRET_KEY = process.env.JWT_SECRET_KEY;
function verifyToken(token) {
try {
// Verify signature and decode payload
const decoded = jwt.verify(token, SECRET_KEY, {
algorithms: ['HS256'] // Explicitly specify allowed algorithms
});
return decoded;
} catch (error) {
// Token is invalid or signature verification failed
throw new Error('Invalid token');
}
}
Example implementation (Python with PyJWT library):
import jwt
import os
SECRET_KEY = os.environ.get('JWT_SECRET_KEY')
def verify_token(token):
try:
# Verify signature and decode payload
decoded = jwt.decode(
token,
SECRET_KEY,
algorithms=['HS256'] # Explicitly specify allowed algorithms
)
return decoded
except jwt.InvalidTokenError:
# Token is invalid or signature verification failed
raise ValueError('Invalid token')
5. Audit existing code: Review all code that processes JWTs to ensure signature verification is enabled and cannot be bypassed. Remove any code that uses decode methods without verification (e.g., jwt.decode() without signature validation).
6. Test thoroughly: Verify that modified or unsigned tokens are rejected by attempting to access protected endpoints with tampered tokens.