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

Description

Improper verification of JWT cryptographic signature.

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