AKRABAT

I recently needed to validate the value created by PHP for its session ID. After a bit of research, I realised that there are two interesting php.ini config settings that relate to this value:

  • session.sid_length is the number of characters in the ID
  • session.sid_bits_per_character controls the set of characters used. From the manual:

    The possible values are ‘4’ (0-9, a-f), ‘5’ (0-9, a-v), and ‘6’ (0-9, a-z, A-Z, “-“, “,”).

Therefore, to validate the session ID we need to create a regular expression that looks for the correct set of characters of the expected length.

I wrote function to do this:

function isValidSessionId(string $sessionId): bool
{
    $sidLength = ini_get('session.sid_length');

    switch (ini_get('session.sid_bits_per_character')) {
        case 6:
            $characterClass = '0-9a-zA-z,-';
            break;
        case 5:
            $characterClass = '0-9a-z';
            break;
        case 4:
            $characterClass = '0-9a-f';
            break;
        default:
            throw new RuntimeException('Unknown value in session.sid_bits_per_character.');
    }
    $pattern = '/^[' . $characterClass . ']{' . $sidLength . '}$/';

    return preg_match($pattern, $sessionId) === 1;
}

You could use it like this:

$name = session_name();
if (isset($_COOKIE[$name])) {
    if (!isValidSessionId($_COOKIE[$name])) {
        // invalid - return an error, just send back a 500 or something
        exit;
    }
}

As far as I can tell, we can’t use session_id() as we haven’t started the session yet, however as the session is just a cookie at the HTTP level, we can use $_COOKIE instead.

Note also that the manual has an excellent section on Sessions and Security which is worth reading.

Source: AKRABAT

By Rob