Fixed bug #13989: Mitigate PHP's RNG vulnerability (thanks to Marcus Krause and Helmu...
authorOliver Hader <oliver.hader@typo3.org>
Wed, 28 Jul 2010 09:05:21 +0000 (09:05 +0000)
committerOliver Hader <oliver.hader@typo3.org>
Wed, 28 Jul 2010 09:05:21 +0000 (09:05 +0000)
git-svn-id: https://svn.typo3.org/TYPO3v4/Core/trunk@8375 709f56b5-9817-0410-a4d7-c38de5d9e867

ChangeLog
t3lib/class.t3lib_div.php
t3lib/class.t3lib_userauth.php
typo3/sysext/install/mod/class.tx_install_ajax.php

index 86593db..08be6b2 100755 (executable)
--- a/ChangeLog
+++ b/ChangeLog
@@ -13,6 +13,7 @@
        * Fixed bug #13957: XSS in template analyzer (thanks to Georg Ringer)
        * Fixed bug #14215: XSS in beuser (thanks to Georg Ringer)
        * Fixed bug #12458: Session fixation possibility in new sesion machanism of the install tool (thanks to Benjamin Mack, Helmut Hummel and Ernesto Baschny)
+       * Fixed bug #13989: Mitigate PHP's RNG vulnerability (thanks to Marcus Krause and Helmut Hummel)
 
 2010-07-27  Steffen Kamper  <steffen@typo3.org>
 
index 47fb39d..a20baaa 100644 (file)
@@ -1583,22 +1583,54 @@ final class t3lib_div {
                if (TYPO3_OS != 'WIN' && ($fh = @fopen('/dev/urandom', 'rb'))) {
                        $output = fread($fh, $count);
                        fclose($fh);
+               } elseif (TYPO3_OS == 'WIN') {
+                       if (class_exists('COM')) {
+                               try {
+                                       $com = new COM('CAPICOM.Utilities.1');
+                                       $output = base64_decode($com->GetRandom($count, 0));
+                               } catch(Exception $e) {
+                                       // CAPICOM not installed
+                               }
+                       }
+                       if ($output === '' && version_compare(PHP_VERSION, '5.3.0', '>=')) {
+                               if (function_exists('mcrypt_create_iv')) {
+                                       $output = mcrypt_create_iv($count, MCRYPT_DEV_URANDOM);
+                               } elseif (function_exists('openssl_random_pseudo_bytes')) {
+                                       $isStrong = null;
+                                       $output = openssl_random_pseudo_bytes($count, $isStrong);
+                                               // skip ssl since it wasn't using the strong algo
+                                       if ($isStrong !== TRUE) {
+                                               $output = '';
+                                       }
+                               }
+                       }
                }
 
-                       // fallback if /dev/urandom is not available
+                       // fallback if other random byte generation failed until now
                if (!isset($output{$count - 1})) {
                                // We initialize with the somewhat random.
                        $randomState = $GLOBALS['TYPO3_CONF_VARS']['SYS']['encryptionKey']
-                                                       . microtime() . getmypid();
+                                                       . base_convert(memory_get_usage() % pow(10, 6), 10, 2)
+                                                       . microtime() . uniqid('') . getmypid();
                        while (!isset($output{$count - 1})) {
-                               $randomState = md5(microtime() . mt_rand() . $randomState);
-                               $output .= md5(mt_rand() . $randomState, true);
+                               $randomState = sha1(microtime() . mt_rand() . $randomState);
+                               $output .= sha1(mt_rand() . $randomState, true);
                        }
                        $output = substr($output, strlen($output) - $count, $count);
                }
                return $output;
        }
 
+       /**
+        * Returns a hex representation of a random byte string.
+        *
+        * @param               integer  Number of hex characters to return
+        * @return              string   Random Bytes
+        */
+       public static function getRandomHexString($count) {
+               return substr(bin2hex(self::generateRandomBytes(intval(($count + 1) / 2))), 0, $count);
+       }
+
        /**
         * Returns a given string with underscores as UpperCamelCase.
         * Example: Converts blog_example to BlogExample
index dfbd452..0173733 100644 (file)
@@ -692,7 +692,7 @@ class t3lib_userAuth {
         * @return      string          The new session ID
         */
        public function createSessionId() {
-               return substr(md5(uniqid('') . getmypid()), 0, $this->hash_length);
+               return t3lib_div::getRandomHexString($this->hash_length);
        }
 
 
index d3089b6..46281c4 100644 (file)
@@ -127,8 +127,7 @@ class tx_install_ajax {
                        header("Content-type: text/plain");
                }
 
-               $bytes = t3lib_div::generateRandomBytes($keyLength);
-               return substr(bin2hex($bytes), -96);
+               return t3lib_div::getRandomHexString($keyLength);
        }
 
        /**