note 121945 added to function.session-create-id
| From: | rowan dot collins at gmail dot com | Date: | Wed, 29 Nov 2017 15:43:12 +0000 |
| Subject: | note 121945 added to function.session-create-id | ||
| Groups: | php.notes | ||
| Request: | Send a blank email to php-notes+get-209258@lists.php.net to get a copy of this message | ||
This function is very hard to replicate precisely in userland code, because if a session is already
started, it will attempt to detect collisions using the new "validate_sid" session handler
callback, which did not exist in earlier PHP versions.
If the handler you are using implements the "create_sid" callback, collisions may be
detected there. This is called when you use session_regenerate_id(), so you could use that to create
a new session, note its ID, then switch back to the old session ID. If no session is started, or the
current handler doesn't implement "create_sid" and "validate_sid", neither
this function nor session_regenerate_id() will guarantee collision resistance anyway.
If you have a suitable definition of random_bytes (a library is available to provide this for
versions right back to PHP 5.3), you can use the following to generate a session ID in the same
format PHP 7.1 would use. $bits_per_character should be 4, 5, or 6, corresponding to the values of
the session.hash_bits_per_character / session.sid_bits_per_character ini setting. You will then need
to detect collisions manually, e.g. by opening the session and confirming that $_SESSION is empty.
<?php
function session_create_random_id($desired_output_length, $bits_per_character)
{
$bytes_needed = ceil($desired_output_length * $bits_per_character / 8);
$random_input_bytes = random_bytes($bytes_needed);
// The below is translated from function bin_to_readable in the PHP source (ext/session/session.c)
static $hexconvtab = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ,-';
$out = '';
$p = 0;
$q = strlen($random_input_bytes);
$w = 0;
$have = 0;
$mask = (1 << $bits_per_character) - 1;
$chars_remaining = $desired_output_length;
while ($chars_remaining--) {
if ($have < $bits_per_character) {
if ($p < $q) {
$byte = ord( $random_input_bytes[$p++] );
$w |= ($byte << $have);
$have += 8;
} else {
// Should never happen. Input must be large enough.
break;
}
}
// consume $bits_per_character bits
$out .= $hexconvtab[$w & $mask];
$w >>= $bits_per_character;
$have -= $bits_per_character;
}
return $out;
}
?>
----
Server IP: 208.43.231.9
Probable Submitter: 62.6.147.196
----
Manual Page -- http://php.net/manual/en/function.session-create-id.php
Edit -- https://master.php.net/note/edit/121945
Del: integrated -- https://master.php.net/note/delete/121945/integrated
Del: useless -- https://master.php.net/note/delete/121945/useless
Del: bad code -- https://master.php.net/note/delete/121945/bad+code
Del: spam -- https://master.php.net/note/delete/121945/spam
Del: non-english -- https://master.php.net/note/delete/121945/non-english
Del: in docs -- https://master.php.net/note/delete/121945/in+docs
Del: other reasons-- https://master.php.net/note/delete/121945
Reject -- https://master.php.net/note/reject/121945
Search -- https://master.php.net/manage/user-notes.php