Session Fixation - PHP

Session Fixation - PHP

Need

Prevention of session hijacking

Context

  • Usage of PHP 7.0 for server-side scripting and web development
  • Usage of Request for making HTTP requests
  • Usage of Auth for User Authentication and Authorization

Description

Non compliant code

        public function postLogin(Request $request)
{
    $credentials = $request->only('email', 'password');

    if (Auth::attempt($credentials)) {
        // Authentication passed...
        return redirect()->intended('dashboard');
    }
}
        
        

The above code is a typical Laravel method for handling user login. It takes a request as a parameter, which contains the user's email and password. It then attempts to authenticate the user with these credentials. If the authentication is successful, the user is redirected to the dashboard.

The vulnerability in this code lies in the fact that the session ID, which is stored in a cookie, doesn't change after a successful login. This is an example of a Session Fixation vulnerability.

In a Session Fixation attack, an attacker can trick a user into using a session ID known to the attacker. After the user logs in, the session ID doesn't change, so the attacker can use the known session ID to impersonate the user. This can lead to unauthorized access and potential data breaches.

In this code, the session ID should be regenerated after a successful login to prevent this from happening.

Steps

  • First, you need to invalidate the old session after a successful login. This can be done by calling a function that regenerates the session ID.
  • Next, you should create a new session for the user. This is to ensure that the user's session is unique and not linked to any previous session.
  • Finally, you should ensure that the session cookie is secure and HttpOnly. This means that it can only be accessed through HTTP requests and not through client-side scripts. This helps to prevent session hijacking.

Compliant code

        public function postLogin(Request $request)
{
    $credentials = $request->only('email', 'password');

    if (Auth::attempt($credentials)) {
        // Invalidate old session and start a new one
        $request->session()->regenerate();

        // Authentication passed...
        return redirect()->intended('dashboard');
    }
}
        
        

The updated code now includes a call to $request->session()->regenerate(); after a successful login attempt. This function call will invalidate the old session and start a new one, effectively preventing session fixation attacks.

In a session fixation attack, an attacker tricks a victim into using a session ID known to the attacker. Then, when the victim logs in, the attacker uses the known session ID to hijack the session. By regenerating the session ID after login, we ensure that any session ID known to the attacker becomes invalid.

In addition, Laravel's session configuration file ( config/session.php) should be set to use secure, HttpOnly cookies. This can be done by setting the secure and http_only options to true. This ensures that the session cookie can only be accessed through HTTP requests, not through client-side scripts, further protecting against session hijacking.

                'secure' => env('SESSION_SECURE_COOKIE', true),
'http_only' => true,

            


Remember to set the SESSION_SECURE_COOKIE environment variable in your .env file to true in a production environment. This will ensure that cookies are only sent over HTTPS, providing another layer of security.

References