Skip to content

JWT Signature Validation Disabled

What does this mean ?

JSON web tokens are a type of access tokens that are widely used in commercial applications. They are based on the JSON format and includes a token signature to ensure the integrity of the token. JSON web tokens provide a secure way to identify the user since the data contained in the payload section cannot be tampered with since the user does not have access to the secret key, she cannot sign the token herself. But if implemented incorrectly, there are ways that an attacker can bypass the security mechanism and forge arbitrary tokens.

What can happen ?

Using a forged token, an attacker could control the victim's account.

Recommendation

Received JWTs must always be validated. When you do that, never ever let the JWT or any of its header parameters drive the verification process alone. Always have a clear cut contract in place, tailored to your application, stipulating the permitted JWT algorithm and other header / payload / claim parameters. Do not attempt to cryptographically process a JWT before this initial screening passes. If you receive a JWT with an unexpected algorithm, type header, etc, discard it, and stop right there.

Sample Code

Vulnerable :

var decodedtoken1 = decoder.Decode(token, secret, verify: false); // Noncompliant: signature should be verified

var decodedtoken2 = new JwtBuilder()
  .WithSecret(secret)
  .Decode(forgedtoken1); // Noncompliant: signature should be verified

Non Vulnerable :

var decodedtoken1 = decoder.Decode(forgedtoken1, secret, verify: true); // Compliant

var decodedtoken2 = new JwtBuilder()
  .WithSecret(secret)
  .MustVerifySignature()
  .Decode(token); // Compliant

Vulnerable :

// Signing:
io.jsonwebtoken.Jwts.builder() // Noncompliant, token is not signed.
  .setSubject(USER_LOGIN)
  .compact();
// Verifying:
io.jsonwebtoken.Jwts.parser().setSigningKey(SECRET_KEY).parse(token).getBody(); // Noncompliant

Non Vulnerable :

// Signing:
Jwts.builder() // Compliant
  .setSubject(USER_LOGIN)
  .signWith(SignatureAlgorithm.HS256, SECRET_KEY)
  .compact();
// Verifying:
Jwts.parser().setSigningKey(SECRET_KEY).parseClaimsJws(token).getBody(); // Compliant

References