Skip to main content

Lack of data validation - Token

Need

Secure and reliable token validation mechanism

Context

  • Usage of Java 8 for developing applications with enhanced features and performance
  • Usage of javax.servlet-api for developing Java web applications using Servlet technology
  • Usage of io.jsonwebtoken for handling JSON Web Tokens (JWT) in authentication and authorization

Description

Non compliant code

import javax.servlet.http.HttpServletRequest;
import io.jsonwebtoken.Jwts;

public class JwtAuthentication {
private static final String SECRET = "SECRET_KEY";

public void validateToken(HttpServletRequest request) {
String token = request.getHeader("Authorization");
Jwts.parser().setSigningKey(SECRET).parseClaimsJws(token);
}
}

The above code is used to parse a JWT token from the Authorization header of an HTTP request and validates it using a secret key.

However, the vulnerability lies in the fact that the code does not check if the JWT token signature is valid or not. This means that if an attacker modifies the token or even removes the signature from the token, the server will still accept the requests.

The Jwts.parser().setSigningKey(SECRET).parseClaimsJws(token); line is responsible for parsing the JWT token. It uses the SECRET key to parse and validate the token. However, it does not throw any exception or error if the signature is invalid or not present, which allows an attacker to modify the token freely.

This lack of data validation makes the application vulnerable to attacks where an attacker can craft a token with escalated privileges and gain unauthorized access to resources.

Steps

  • Implement signature validation for the JWT access token
  • Verify the integrity of the token by checking the signature
  • Use a secure secret key for signing the token
  • Ensure that the secret key is kept confidential and not exposed in the code
  • Consider using a secure token library or framework that handles token validation and verification automatically

Compliant code

import javax.servlet.http.HttpServletRequest;
import io.jsonwebtoken.Claims;
import io.jsonwebtoken.Jws;
import io.jsonwebtoken.JwtException;
import io.jsonwebtoken.Jwts;

public class JwtAuthentication {
private static final String SECRET = "SECRET_KEY";

public boolean validateToken(HttpServletRequest request) {
String token = request.getHeader("Authorization");
try {
Jws<Claims> claimsJws = Jwts.parser().setSigningKey(SECRET).parseClaimsJws(token);
return true;
} catch (JwtException e) {
return false;
}
}
}

The updated code now validates the JWT token signature. The validateToken method now returns a boolean value indicating whether the token is valid or not.

The Jwts.parser().setSigningKey(SECRET).parseClaimsJws(token) line parses the JWT token and validates its signature. If the signature is valid, it returns the parsed claims. If the signature is invalid, it throws a JwtException.

The try-catch block is used to handle the JwtException. If a JwtException is thrown, the method returns false, indicating that the token is invalid. If no exception is thrown, the method returns true, indicating that the token is valid.

The SECRET key used for signing the token is kept confidential and not exposed in the code. It's recommended to store this key in a secure location, such as environment variables or a secure key vault.

This code ensures that the integrity of the JWT token is verified by checking the signature. It's recommended to use a secure token library or framework that handles token validation and verification automatically.

References