logo

Concurrent sessions control bypass - Java


Need

Enforcement of concurrent session control


Context

  1. Usage of Java 8 for developing applications with enhanced features and performance improvements
  2. Usage of javax.servlet-api for building Java web applications with Servlets

Description

Insecure Code Example

import javax.servlet.http.HttpSession;
import javax.servlet.http.HttpServletRequest;

public void handleRequest(HttpServletRequest request) {
    HttpSession session = request.getSession(false);
    if (session != null) {
        // Do something with the session
    } else {
        session = request.getSession(true);
    }
}

The above code is an example of a Servlet that handles HTTP requests in a Java-based web application. Here, the `handleRequest` method is trying to retrieve an existing HTTP session, if it exists, otherwise it creates a new one. The vulnerability lies in the fact that this code does not properly handle concurrent sessions. When a user is already logged in and has an active session, and then they try to start a new session from a different browser or device, this code will simply create a new session for them. This allows the user to bypass the concurrent session control. The problem arises when the application is not checking if there is already an active session for the user. If there is, the application should not create a new session, but instead return an error message to the user, notifying them that they are already logged in elsewhere. This lack of control can lead to situations where a user can have multiple active sessions at the same time, which can cause issues with data consistency and can potentially be exploited by an attacker to gain unauthorized access to the system.

Steps

  1. Implement a mechanism to track and limit the number of concurrent sessions per user.
  2. When a user tries to start a new session, check if the maximum number of concurrent sessions has been reached.
  3. If the maximum number of sessions has been reached, prevent the user from starting a new session and display an appropriate error message.
  4. If the maximum number of sessions has not been reached, allow the user to start a new session.
  5. Ensure that the session management mechanism is secure and cannot be bypassed.

Secure Code Example

import javax.servlet.http.HttpSession;
import javax.servlet.http.HttpServletRequest;
import java.util.concurrent.ConcurrentHashMap;

public class SessionManager {
    private static final int MAX_SESSIONS_PER_USER = 1; // Set your limit
    private static ConcurrentHashMap<String, HttpSession> activeSessions = new ConcurrentHashMap<>();

    public static void handleRequest(HttpServletRequest request) {
        HttpSession session = request.getSession(false);
        if (session != null && session.getAttribute("username") != null) {
            if (activeSessions.contains(session.getAttribute("username"))) {
                // Do something with the session
            } else {
                // Session exists but not in activeSessions map, so invalidate it
                session.invalidate();
                throw new RuntimeException("Maximum number of sessions reached");
            }
        } else {
            if (activeSessions.size() < MAX_SESSIONS_PER_USER) {
                session = request.getSession(true);
                activeSessions.put((String) session.getAttribute("username"), session);
            } else {
                throw new RuntimeException("Maximum number of sessions reached");
            }
        }
    }
}

The above code fixes the vulnerability by implementing a mechanism to track and limit the number of concurrent sessions per user. A `ConcurrentHashMap` named `activeSessions` is used to store the active sessions. The key is the username and the value is the session. When a user tries to start a new session, the `handleRequest` method checks if the maximum number of concurrent sessions (`MAX_SESSIONS_PER_USER`) has been reached. If the maximum number of sessions has been reached, the user is prevented from starting a new session and a `RuntimeException` with an appropriate error message is thrown. If the maximum number of sessions has not been reached, the user is allowed to start a new session and the session is added to the `activeSessions` map. If a session exists but is not in the `activeSessions` map, it is invalidated. This ensures that the session management mechanism is secure and cannot be bypassed.


References

  • 301 - Concurrent sessions control bypass

  • Last updated

    2023/09/18