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:03:58 +0000 (09:03 +0000)
committerOliver Hader <oliver.hader@typo3.org>
Wed, 28 Jul 2010 09:03:58 +0000 (09:03 +0000)
git-svn-id: https://svn.typo3.org/TYPO3v4/Core/branches/TYPO3_4-2@8372 709f56b5-9817-0410-a4d7-c38de5d9e867

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

index c3c7530..d911242 100755 (executable)
--- a/ChangeLog
+++ b/ChangeLog
@@ -13,6 +13,7 @@
        * 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 #12736: XSS in setup module (thanks to Georg Ringer)
+       * Fixed bug #13989: Mitigate PHP's RNG vulnerability (thanks to Marcus Krause and Helmut Hummel)
 
 2010-07-21  Ingo Renner  <ingo@typo3.org>
 
index 82a1f9c..a0458ef 100755 (executable)
@@ -1529,16 +1529,38 @@ 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);
                }
@@ -1546,6 +1568,16 @@ final class t3lib_div {
        }
 
        /**
+        * 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);
+       }
+
+       /**
         * Checks if a given string is a Uniform Resource Locator (URL).
         *
         * @param       string          $url: The URL to be validated
index 0a54e50..3505a0a 100755 (executable)
@@ -228,7 +228,7 @@ class t3lib_userAuth {
                        // If new session or client tries to fix session...
                if (!$id || !$this->isExistingSessionRecord($id))       {
                                // New random session-$id is made
-                       $id = substr(md5(uniqid('').getmypid()),0,$this->hash_length);
+                       $id = t3lib_div::getRandomHexString($this->hash_length);
                                // New session
                        $this->newSessionID = TRUE;
                }
index 78c6a30..aefb38e 100644 (file)
@@ -71,7 +71,7 @@ class tx_install_eid {
 
 
        /**
-        * Main function which creates the ecryption key for the install tools AJAX call 
+        * Main function which creates the ecryption key for the install tools AJAX call
         * It stores the key in $this->content
         *
         * @return      void
@@ -104,9 +104,8 @@ class tx_install_eid {
                if (!headers_sent()) {
                        header("Content-type: text/plain");
                }
-               
-               $bytes = t3lib_div::generateRandomBytes($keyLength);
-               return substr(bin2hex($bytes), -96);
+
+               return t3lib_div::getRandomHexString($keyLength);
        }
 
        /**