JWT Signature Verification Bypass
ID |
java.jwt_signature_verification_bypass |
Severity |
high |
Resource |
Cryptography |
Language |
Java |
Tags |
CWE:347, NIST.SP.800-53, OWASP:2021:A3, OWASP:2021:A7, PCI-DSS:6.5.10, PCI-DSS:6.5.6, PCI-DSS:6.5.8 |
Rationale
JWT signature verification bypass refers to a scenario where a JSON Web Token, designed to be a secure way to transmit information between parties, is not properly checked for a valid signature.
This can allow attackers to forge tokens, gaining unauthorized access to protected resources or services.
In Java, JWT handling is often done using libraries like jjwt
. For example, consider the following sample code using the jjwt
library:
import io.jsonwebtoken.Jwts;
public class JwtVerifier {
public void badJwt(String token) {
Jwts.parserBuilder() // FLAW explain.contains=The signature is not verified with the 'parse' method. Consider using 'parseClaimsJws' or 'parsePlaintextJws' instead
.setSigningKey(key)
.build()
.parse(token);
}
}
In the example above, the signature is not verified with the parse
method. Neither parseClaimsJws
and parsePlaintextJws
are safe.
Remediation
To remediate the JWT signature verification bypass, ensure that you are properly configuring the JWT parser in use, and always verifying the token signature with a trusted public key or secret.
Furthermore, make sure your JWT libraries are updated to the latest versions, which often address security vulnerabilities and provide enhanced capabilities. Additionally, it’s important to apply similar best practices across all environments where JWTs are used or processed to maintain consistent security assurances.
Here’s how you can correctly verify a JWT signature using the jjwt
library:
import io.jsonwebtoken.Claims;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.security.Keys;
import java.security.Key;
public class SecureJwtVerifier {
public Claims parseJwtSecurely(String jwtToken) {
// Securely parse and validate the JWT token by verifying its signature
return Jwts.parserBuilder()
.setSigningKey(key)
.build()
.parseClaimsJws(jwtToken)
.getBody();
}
}
The critical change involves using parseClaimsJws
or parseClaimsJws
methods or by overriding the onPlaintextJws
or onClaimsJws
of JwtHandlerAdapter
.
References
-
CWE-347 : Improper Verification of Cryptographic Signature