Insecure session expiration time - PHP

Insecure session expiration time - PHP

Need

Enforce secure session expiration time

Context

  • Usage of PHP 7.0 for server-side scripting and web development
  • Usage of the Str library for string manipulation and operations

Description

Non compliant code

        // config/session.php

return [
    'driver' => env('SESSION_DRIVER', 'file'),
    'lifetime' => env('SESSION_LIFETIME', 120),
    'expire_on_close' => false,
    'encrypt' => false,
    'files' => storage_path('framework/sessions'),
    'connection' => env('SESSION_CONNECTION', null),
    'table' => 'sessions',
    'store' => env('SESSION_STORE', null),
    'lottery' => [2, 100],
    'cookie' => env(
        'SESSION_COOKIE',
        Str::slug(env('APP_NAME', 'laravel'), '_').'_session'
    ),
    'path' => '/',
    'domain' => env('SESSION_DOMAIN', null),
    'secure' => env('SESSION_SECURE_COOKIE', false),
    'http_only' => true,
    'same_site' => 'lax',
];
        
        

The code above represents the default configuration for sessions in Laravel. The lifetime key in the array is set to 120 by default, which means that the session will not expire until 120 minutes (2 hours) of inactivity. This is a security vulnerability because it allows an attacker who has somehow obtained a user's session ID to use their session for up to 2 hours, even if the legitimate user is not currently active.

The expire_on_close key is set to false by default, which means that the session will not expire when the user closes their browser. This is another security vulnerability because it allows an attacker to use a user's session even after the user has closed their browser.

The encrypt key is set to false by default, which means that the session data is not encrypted. This is a security vulnerability because it allows an attacker who has somehow obtained the session data to read it.

The http_only key is set to true by default, which means that the session cookie can only be accessed through HTTP and not through JavaScript. This is a security measure that helps to prevent session hijacking through cross-site scripting (XSS) attacks. However, it does not prevent session hijacking through other means, such as session sidejacking or session fixation attacks.

The same_site key is set to lax by default, which means that the session cookie will only be sent with same-site requests. This is a security measure that helps to prevent cross-site request forgery (CSRF) attacks. However, it does not prevent session hijacking through other means, such as session sidejacking or session fixation attacks.

Steps

  • Identify the configuration setting for session lifetime. In the provided code, it's 'SESSION_LIFETIME'.
  • Change the value of 'SESSION_LIFETIME' to 5. This value is in minutes, so setting it to 5 will make sessions expire after 5 minutes of inactivity.
  • Ensure that the 'expire_on_close' setting is set to true. This will make sure that the session expires when the user closes the browser.
  • Test the application to ensure that sessions are indeed expiring after 5 minutes of inactivity and when the browser is closed.

Compliant code

        // config/session.php

return [
    'driver' => env('SESSION_DRIVER', 'file'),
    'lifetime' => env('SESSION_LIFETIME', 5),
    'expire_on_close' => true,
    'encrypt' => false,
    'files' => storage_path('framework/sessions'),
    'connection' => env('SESSION_CONNECTION', null),
    'table' => 'sessions',
    'store' => env('SESSION_STORE', null),
    'lottery' => [2, 100],
    'cookie' => env(
        'SESSION_COOKIE',
        Str::slug(env('APP_NAME', 'laravel'), '_').'_session'
    ),
    'path' => '/',
    'domain' => env('SESSION_DOMAIN', null),
    'secure' => env('SESSION_SECURE_COOKIE', false),
    'http_only' => true,
    'same_site' => 'lax',
];
        
        

The above code is a fixed version of the Laravel session configuration file. The vulnerability was that user sessions did not expire after 5 minutes of inactivity. This could potentially allow unauthorized users to hijack a session if the original user left their browser open.

The fix involves two changes:

1. The 'lifetime' setting, which controls how long a session lasts before it expires due to inactivity, has been changed from 120 minutes to 5 minutes. This means that if a user does not interact with the application for 5 minutes, their session will automatically expire.

2. The 'expire_on_close' setting, which controls whether a session expires when the user closes their browser, has been set to true. This means that a session will automatically expire when the user closes their browser, regardless of how long they were inactive.

These changes ensure that user sessions are secure and expire appropriately, reducing the risk of session hijacking. After implementing these changes, it's important to test the application to ensure that sessions are indeed expiring after 5 minutes of inactivity and when the browser is closed.

References