Skip to content

JWT Signature Validation Disabled

What does this mean ?

JSON web tokens are a sort of access token commonly used in commercial applications. They use the JSON format and include a token signature to confirm the token's integrity. JSON web tokens provide a safe means to identify the user since the data in the payload section cannot be tampered with. and the user cannot sign the token herself because she does not have access to the secret key. However, if configured poorly, an attacker can circumvent the security system and generate arbitrary tokens.

What can happen ?

An attacker might get access to the victim's account by using a falsified token.

Recommendation

Validation of received JWTs is always required. When doing so, never allow the JWT or any of its header parameters drive the verification process on their own. Always have a clear contract in place that is suited to your application and specifies the allowed JWT algorithm as well as other header / payload / claim elements. Do not attempt to cryptographically process a JWT until this initial screening has been completed. If you get a JWT with an unusual algorithm, type header, or other information, disregard 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

Vulnerable :

const jwt = require('jsonwebtoken');

const token = jwt.sign({ foo: 'bar' }, key, { algorithm: 'none' }); // Vulnerable

jwt.verify(token, key, { expiresIn: 360000 * 5, algorithms: ['RS256', 'none'] }, callbackcheck);

Non Vulnerable :

const jwt = require('jsonwebtoken');

const token = jwt.sign({ foo: 'bar' }, key, { algorithm: 'HS256' }); // Non Vulnerable

jwt.verify(token, key, { expiresIn: 360000 * 5, algorithms: ['HS256'] }, callbackcheck);

Vulnerable :

const jwt = require('jsonwebtoken');

const token = jwt.sign({ foo: 'bar' }, key, { algorithm: 'none' }); // Vulnerable

jwt.verify(token, key, { expiresIn: 360000 * 5, algorithms: ['RS256', 'none'] }, callbackcheck);

Non Vulnerable :

const jwt = require('jsonwebtoken');

const token = jwt.sign({ foo: 'bar' }, key, { algorithm: 'HS256' }); // Non Vulnerable

jwt.verify(token, key, { expiresIn: 360000 * 5, algorithms: ['HS256'] }, callbackcheck);

References