From 487ccc9c8a21cb6338aab7173b3adda194d29c26 Mon Sep 17 00:00:00 2001 From: Andrey Andreev Date: Wed, 27 Aug 2014 16:26:23 +0300 Subject: Add CI_Security::get_random_bytes() for CSRF & XSS token generation --- system/core/Security.php | 61 ++++++++++++++++++++++++++++++++++++++++++------ 1 file changed, 54 insertions(+), 7 deletions(-) (limited to 'system') diff --git a/system/core/Security.php b/system/core/Security.php index bb0670500..bc224e7e3 100755 --- a/system/core/Security.php +++ b/system/core/Security.php @@ -77,7 +77,7 @@ class CI_Security { * * @var string */ - protected $_xss_hash = ''; + protected $_xss_hash; /** * CSRF Hash @@ -86,7 +86,7 @@ class CI_Security { * * @var string */ - protected $_csrf_hash = ''; + protected $_csrf_hash; /** * CSRF Expire time @@ -227,7 +227,7 @@ class CI_Security { { // Nothing should last forever unset($_COOKIE[$this->_csrf_cookie_name]); - $this->_csrf_hash = ''; + $this->_csrf_hash = NULL; } $this->_csrf_set_hash(); @@ -538,9 +538,12 @@ class CI_Security { */ public function xss_hash() { - if ($this->_xss_hash === '') + if ($this->_xss_hash === NULL) { - $this->_xss_hash = md5(uniqid(mt_rand())); + $rand = $this->get_random_bytes(16); + $this->_xss_hash = ($rand === FALSE) + ? md5(uniqid(mt_rand(), TRUE)) + : bin2hex($rand); } return $this->_xss_hash; @@ -548,6 +551,46 @@ class CI_Security { // -------------------------------------------------------------------- + /** + * Get random bytes + * + * @param int $length Output length + * @return string + */ + public function get_random_bytes($length) + { + if (empty($length) OR ! ctype_digit($length)) + { + return FALSE; + } + + // Unfortunately, none of the following PRNGs is guaranteed to exist ... + if (defined(MCRYPT_DEV_URANDOM) && ($output = mcrypt_create_iv($length, MCRYPT_DEV_URANDOM)) !== FALSE) + { + return $output; + } + + + if (is_readable('/dev/urandom') && ($fp = fopen('/dev/urandom', 'rb')) !== FALSE) + { + $output = fread($fp, $length); + fclose($fp); + if ($output !== FALSE) + { + return $output; + } + } + + if (function_exists('openssl_random_pseudo_bytes')) + { + return openssl_random_pseudo_bytes($length); + } + + return FALSE; + } + + // -------------------------------------------------------------------- + /** * HTML Entities Decode * @@ -915,7 +958,7 @@ class CI_Security { */ protected function _csrf_set_hash() { - if ($this->_csrf_hash === '') + if ($this->_csrf_hash === NULL) { // If the cookie exists we will use its value. // We don't necessarily want to regenerate it with @@ -927,7 +970,11 @@ class CI_Security { return $this->_csrf_hash = $_COOKIE[$this->_csrf_cookie_name]; } - $this->_csrf_hash = md5(uniqid(mt_rand(), TRUE)); + $rand = $this->get_random_bytes(16); + $this->_csrf_hash = ($rand === FALSE) + ? md5(uniqid(mt_rand(), TRUE)) + : bin2hex($rand); + $this->csrf_set_cookie(); } -- cgit v1.2.3-24-g4f1b