Skip to main content

Insecurely generated token - Lifespan

Need

Securely generate session tokens with appropriate expiration times

Context

  • Usage of Java for building robust and scalable applications
  • Usage of javax.servlet.http.Cookie for handling HTTP cookies in Java servlets
  • Usage of HttpServletResponse for handling HTTP responses in Java Servlets

Description

Non compliant code

import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletResponse;

public class SessionManager {
private static final int FIVE_DAYS_IN_SECONDS = 60 * 60 * 24 * 5;

public void createSession(String sessionId, HttpServletResponse response) {
Cookie sessionCookie = new Cookie("sessionId", sessionId);
sessionCookie.setMaxAge(FIVE_DAYS_IN_SECONDS);
response.addCookie(sessionCookie);
}
}

The above code snippet is a simple example of a session manager in a Java backend application that uses javax.servlet. The SessionManager class has a method createSession which takes a sessionId and a HttpServletResponse as parameters.

The sessionId is presumably generated elsewhere in the application and passed to this method, which then creates a new Cookie object with the name "sessionId" and the value of the sessionId parameter.

The vulnerability lies in the line sessionCookie.setMaxAge(FIVE_DAYS_IN_SECONDS);. This sets the maximum age of the cookie to approximately 5 days (60 seconds * 60 minutes * 24 hours * 5 days).

This is a security vulnerability because it allows for a long-lived session. If an attacker were to somehow get hold of a user's session token, they would have access to that user's session for up to 5 days. This gives the attacker a large window of opportunity to exploit the user's session.

Ideally, session tokens should have a short lifespan and be refreshed frequently to limit the potential damage if an attacker were to gain access to a user's session token.

Steps

  • Reduce the lifespan of the session token to a shorter duration.
  • Use a cryptographically secure random number generator to generate the session token.
  • Implement a mechanism to revoke or invalidate session tokens when necessary.
  • Implement additional security measures such as session expiration checks on the server-side.
  • Consider implementing multi-factor authentication to enhance the security of the session tokens.

Compliant code

import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletResponse;
import java.security.SecureRandom;

public class SessionManager {
private static final int THIRTY_MINUTES_IN_SECONDS = 60 * 30;
private static final SecureRandom secureRandom = new SecureRandom();

public void createSession(HttpServletResponse response) {
String sessionId = generateSecureToken();
Cookie sessionCookie = new Cookie("sessionId", sessionId);
sessionCookie.setMaxAge(THIRTY_MINUTES_IN_SECONDS);
response.addCookie(sessionCookie);
}

private String generateSecureToken() {
byte[] randomBytes = new byte[24];
secureRandom.nextBytes(randomBytes);
return Base64.getEncoder().encodeToString(randomBytes);
}
}

The updated code now generates session tokens using a cryptographically secure random number generator (SecureRandom). This ensures that the session tokens are unpredictable and resistant to guessing attacks.

The lifespan of the session tokens has been reduced to 30 minutes (THIRTY_MINUTES_IN_SECONDS). This reduces the window of opportunity for an attacker to use a stolen session token.

The generateSecureToken() method generates a new secure token each time a session is created. This token is then set as a cookie in the user's browser.

Please note that this code does not include mechanisms for revoking or invalidating session tokens, server-side session expiration checks, or multi-factor authentication. These features should be implemented as part of a comprehensive session management strategy to further enhance the security of the session tokens.

References