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