Session Management in PHP – Part2

control garbage collection:

PHP session management has a built-in garbage collection mechanism that ensures unused session files are eventually cleaned up. This is important for two reasons: it prevents the directory from filling up with session files that can cause performance to degrade and, more importantly, it reduces the risk of someone guessing session IDs and hijacking an old unused session.

There are two parameters that control garbage collection: session.gc_maxlifetime and session.gc_probability, both defined in the php.ini file. A garbage collection process is run when a session is initialized, for example, when session_start( ) is called. Each session is examined by the garbage collection process, and any sessions that have not been accessed for a specified period of time are removed. This period is specified as seconds of inactivity in the gc_maxlifetime parameter-the default value being 1,440 seconds. The file-based session management uses the update time of the file to determine the last access. To prevent the garbage collection process from removing active session files, PHP must modify the update time of the file when session variables are read, not just when they are written.


Sessions can provide a way for a hacker to break into a system. Sessions can be open to hijacking; a hacker can take over after a legitimate user has logged into an application. Most session fixation attacks simply use a link or a protocol-level redirect to send a user to a remote site with a session identifier appended to the URL. The user likely won’t notice, since the site will behave exactly the same. Because the attacker chose the session identifier, it is already known, and this can be used to launch impersonation attacks such as session hijacking.

A simplistic attack such as this is quite easy to prevent. If there isn’t an active session associated with a session identifier that the user is presenting, then regenerate it just to be sure:



if (!isset($_SESSION['initiated']))
    $_SESSION['initiated'] = true;


The problem with such a simplistic defense is that an attacker can simply initialize a session for a particular session identifier, and then use that identifier to launch the attack.

Let’s modify the session mechanism to perform an extra check:



if (isset($_SESSION['HTTP_USER_AGENT']))
        /* Prompt for password */


Now an attacker must not only present a valid session identifier, but also the correct User-Agent header that is associated with the session. This complicates things slightly, and it is therefore a bit more secure.

Imagine if we required the user to pass the MD5 of the User-Agent in each request. An attacker could no longer just recreate the headers that the victim’s requests contain, but it would also be necessary to pass this extra bit of information. While guessing the construction of this particular token isn’t too difficult, we can complicate such guesswork by simply adding an extra bit of randomness to the way we construct the token:

<?php $string = $_SERVER[‘HTTP_USER_AGENT’];

$string .= ‘SHIFLETT’;

/* Add any other data that is consistent */

$fingerprint = md5($string); ?>

Keeping in mind that we’re passing the session identifier in a cookie, and this already requires that an attack be used to compromise this cookie (and likely all HTTP headers as well), we should pass this fingerprint as a URL variable. This must be in all URLs as if it were the session identifier, because both should be required in order for a session to be automatically continued (in addition to all checks passing).


Leave a Reply

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: