Bug #53034
closedAnonymous session is not unique
100%
Description
PHP 5.3.12
Apache 2.2.22 (Win32)
OS W2008R2 (also occurs in Win7)
Typo3 4.6.3
sometimes the fe_typo_user cookie contains an id which was already in use. After some researching I found out that under Window the algorithm for generating random values isn't really random
from t3lib/class.t3lib_div.php:
public static function generateRandomBytes($bytesToReturn) { // Cache 4k of the generated bytestream. static $bytes = ''; $bytesToGenerate = max(4096, $bytesToReturn); // if we have not enough random bytes cached, we generate new ones if (!isset($bytes{$bytesToReturn - 1})) { if (TYPO3_OS === 'WIN') { // Openssl seems to be deadly slow on Windows, so try to use mcrypt // Windows PHP versions have a bug when using urandom source (see #24410) $bytes .= self::generateRandomBytesMcrypt($bytesToGenerate, MCRYPT_RAND); } else { // Try to use native PHP functions first, precedence has openssl $bytes .= self::generateRandomBytesOpenSsl($bytesToGenerate); if (!isset($bytes{$bytesToReturn - 1})) { $bytes .= self::generateRandomBytesMcrypt($bytesToGenerate, MCRYPT_DEV_URANDOM); } // If openssl and mcrypt failed, try /dev/urandom if (!isset($bytes{$bytesToReturn - 1})) { $bytes .= self::generateRandomBytesUrandom($bytesToGenerate); } } // Fall back if other random byte generation failed until now if (!isset($bytes{$bytesToReturn - 1})) { $bytes .= self::generateRandomBytesFallback($bytesToReturn); } } // get first $bytesToReturn and remove it from the byte cache $output = substr($bytes, 0, $bytesToReturn); $bytes = substr($bytes, $bytesToReturn); return $output; }
the function generateRandomBytesMcrypt() uses PHPs mcrypt_create_iv($size,$source). According to PHPs documentation since 5.3 it is not neccessary to call srand() anymore before calling mcrypt_create_iv() - but this does not seem to be the case if called with $source=MCRYPT_RAND. To isolate this behaviour I used the following console script (this is basically what happens under Windows):
$arr = array(); for ($i=0;$i< 10000;$i++) { $arr[$i]=bin2hex(substr(mcrypt_create_iv(4096,MCRYPT_RAND),0,8)); } print_r(array_count_values($arr));
I got serveral duplicates. However also the use of variable static $bytes does not seem to make sense as Apache seperates the static areas of its requests.
Replacing MCRYPT_RAND with MCRYPT_DEV_URANDOM t3lib/class.t3lib_div.php for windows seems to deliver unique results. Also calling srand() works.