From 103a4263fe8c2715f622355ee7d76114d015f242 Mon Sep 17 00:00:00 2001 From: Andrey Andreev Date: Mon, 3 Oct 2016 11:19:11 +0300 Subject: Fix #4823 --- .../Session/drivers/Session_files_driver.php | 27 ++++++++++++++++++++-- 1 file changed, 25 insertions(+), 2 deletions(-) (limited to 'system/libraries/Session') diff --git a/system/libraries/Session/drivers/Session_files_driver.php b/system/libraries/Session/drivers/Session_files_driver.php index bf4df8b20..5f05396c0 100644 --- a/system/libraries/Session/drivers/Session_files_driver.php +++ b/system/libraries/Session/drivers/Session_files_driver.php @@ -76,6 +76,13 @@ class CI_Session_files_driver extends CI_Session_driver implements SessionHandle */ protected $_file_new; + /** + * mbstring.func_override flag + * + * @var bool + */ + protected static $func_override; + // ------------------------------------------------------------------------ /** @@ -98,6 +105,8 @@ class CI_Session_files_driver extends CI_Session_driver implements SessionHandle log_message('debug', 'Session: "sess_save_path" is empty; using "session.save_path" value from php.ini.'); $this->_config['save_path'] = rtrim(ini_get('session.save_path'), '/\\'); } + + isset(self::$func_override) OR self::$func_override = (extension_loaded('mbstring') && ini_get('mbstring.func_override')); } // ------------------------------------------------------------------------ @@ -187,7 +196,7 @@ class CI_Session_files_driver extends CI_Session_driver implements SessionHandle } $session_data = ''; - for ($read = 0, $length = filesize($this->_file_path.$session_id); $read < $length; $read += strlen($buffer)) + for ($read = 0, $length = filesize($this->_file_path.$session_id); $read < $length; $read += self::strlen($buffer)) { if (($buffer = fread($this->_file_handle, $length - $read)) === FALSE) { @@ -368,4 +377,18 @@ class CI_Session_files_driver extends CI_Session_driver implements SessionHandle return $this->_success; } -} \ No newline at end of file + // -------------------------------------------------------------------- + + /** + * Byte-safe strlen() + * + * @param string $str + * @return int + */ + protected static function strlen($str) + { + return (self::$func_override) + ? mb_strlen($str, '8bit') + : strlen($str); + } +} -- cgit v1.2.3-24-g4f1b From 6c6ee1a1e73b3f8a93ca031107bec35e56272a0a Mon Sep 17 00:00:00 2001 From: Andrey Andreev Date: Sat, 22 Oct 2016 16:33:06 +0300 Subject: Close #4830, #3649 --- system/libraries/Session/Session.php | 36 ++++++++++++++++++++-- .../Session/drivers/Session_files_driver.php | 18 +++++++++-- 2 files changed, 48 insertions(+), 6 deletions(-) (limited to 'system/libraries/Session') diff --git a/system/libraries/Session/Session.php b/system/libraries/Session/Session.php index 3b391a8ef..5aac12f36 100644 --- a/system/libraries/Session/Session.php +++ b/system/libraries/Session/Session.php @@ -57,6 +57,7 @@ class CI_Session { protected $_driver = 'files'; protected $_config; + protected $_sid_regexp; // ------------------------------------------------------------------------ @@ -99,6 +100,7 @@ class CI_Session { // Configuration ... $this->_configure($params); + $this->_config['_sid_regexp'] = $this->_sid_regexp; $class = new $class($this->_config); if ($class instanceof SessionHandlerInterface) @@ -131,7 +133,7 @@ class CI_Session { if (isset($_COOKIE[$this->_config['cookie_name']]) && ( ! is_string($_COOKIE[$this->_config['cookie_name']]) - OR ! preg_match('/^[0-9a-f]{40}$/', $_COOKIE[$this->_config['cookie_name']]) + OR ! preg_match('#\A'.$this->_sid_regexp.'\z#', $_COOKIE[$this->_config['cookie_name']]) ) ) { @@ -315,8 +317,36 @@ class CI_Session { ini_set('session.use_strict_mode', 1); ini_set('session.use_cookies', 1); ini_set('session.use_only_cookies', 1); - ini_set('session.hash_function', 1); - ini_set('session.hash_bits_per_character', 4); + + if (PHP_VERSION_ID < 70100) + { + if ((int) ini_get('session.hash_function') === 0) + { + ini_set('session.hash_function', 1); + ini_set('session.hash_bits_per_character', $bits_per_character = 4); + } + else + { + $bits_per_character = (int) ini_get('session.hash_bits_per_character'); + } + } + elseif ((int) ini_get('session.sid_length') < 40 && ($bits_per_character = (int) ini_get('session.sid_bits_per_character')) === 4) + { + ini_set('session.sid_length', 40); + } + + switch ($bits_per_character) + { + case 4: + $this->_sid_regexp = '[0-9a-f]{40,}'; + break; + case 5: + $this->_sid_regexp = '[0-9a-v]{40,}'; + break; + case 6: + $this->_sid_regexp = '[0-9a-zA-Z,-]{40,}'; + break; + } } // ------------------------------------------------------------------------ diff --git a/system/libraries/Session/drivers/Session_files_driver.php b/system/libraries/Session/drivers/Session_files_driver.php index 5f05396c0..37315d3cd 100644 --- a/system/libraries/Session/drivers/Session_files_driver.php +++ b/system/libraries/Session/drivers/Session_files_driver.php @@ -76,6 +76,13 @@ class CI_Session_files_driver extends CI_Session_driver implements SessionHandle */ protected $_file_new; + /** + * Validate SID regular expression + * + * @var string + */ + protected $_sid_regexp; + /** * mbstring.func_override flag * @@ -106,6 +113,8 @@ class CI_Session_files_driver extends CI_Session_driver implements SessionHandle $this->_config['save_path'] = rtrim(ini_get('session.save_path'), '/\\'); } + $this->_sid_regexp = $this->_config['_sid_regexp']; + isset(self::$func_override) OR self::$func_override = (extension_loaded('mbstring') && ini_get('mbstring.func_override')); } @@ -352,10 +361,13 @@ class CI_Session_files_driver extends CI_Session_driver implements SessionHandle $ts = time() - $maxlifetime; + $pattern = ($this->_config['match_ip'] === TRUE) + ? '[0-9a-f]{32}' + : ''; + $pattern = sprintf( - '/^%s[0-9a-f]{%d}$/', - preg_quote($this->_config['cookie_name'], '/'), - ($this->_config['match_ip'] === TRUE ? 72 : 40) + '#\A%s'.$pattern.$this->_sid_regexp.'\z#', + preg_quote($this->_config['cookie_name']) ); while (($file = readdir($directory)) !== FALSE) -- cgit v1.2.3-24-g4f1b From 2f760877c313871e5066b93b0b1aa76428c09fb6 Mon Sep 17 00:00:00 2001 From: Andrey Andreev Date: Thu, 27 Oct 2016 16:39:12 +0300 Subject: Fix #4874 --- system/libraries/Session/Session.php | 63 ++++++++++++++++++++++++++++++------ 1 file changed, 54 insertions(+), 9 deletions(-) (limited to 'system/libraries/Session') diff --git a/system/libraries/Session/Session.php b/system/libraries/Session/Session.php index 5aac12f36..ea7853108 100644 --- a/system/libraries/Session/Session.php +++ b/system/libraries/Session/Session.php @@ -318,35 +318,80 @@ class CI_Session { ini_set('session.use_cookies', 1); ini_set('session.use_only_cookies', 1); + $this->_configure_sid_length(); + } + + // ------------------------------------------------------------------------ + + /** + * Configure session ID length + * + * To make life easier, we used to force SHA-1 and 4 bits per + * character on everyone. And of course, someone was unhappy. + * + * Then PHP 7.1 broke backwards-compatibility because ext/session + * is such a mess that nobody wants to touch it with a pole stick, + * and the one guy who does, nobody has the energy to argue with. + * + * So we were forced to make changes, and OF COURSE something was + * going to break and now we have this pile of shit. -- Narf + * + * @return void + */ + protected function _configure_sid_length() + { if (PHP_VERSION_ID < 70100) { - if ((int) ini_get('session.hash_function') === 0) + $hash_function = ini_get('session.hash_function'); + if (ctype_digit($hash_function)) + { + if ($hash_function !== '1') + { + ini_set('session.hash_function', 1); + $bits = 160; + } + } + elseif ( ! in_array($hash_function, hash_algos(), TRUE)) { ini_set('session.hash_function', 1); - ini_set('session.hash_bits_per_character', $bits_per_character = 4); + $bits = 160; } - else + elseif (($bits = strlen(hash($hash_function, 'dummy', false)) * 4) < 160) { - $bits_per_character = (int) ini_get('session.hash_bits_per_character'); + ini_set('session.hash_function', 1); + $bits = 160; } + + $bits_per_character = (int) ini_get('session.hash_bits_per_character'); + $sid_length = $bits * $bits_per_character; } - elseif ((int) ini_get('session.sid_length') < 40 && ($bits_per_character = (int) ini_get('session.sid_bits_per_character')) === 4) + else { - ini_set('session.sid_length', 40); + $bits_per_character = (int) ini_get('session.sid_bits_per_character'); + $sid_length = (int) ini_get('session.sid_length'); + if (($bits = $sid_length * $bits_per_character) < 160) + { + // Add as many more characters as necessary to reach at least 160 bits + $sid_length += (int) ceil((160 % $bits) / $bits_per_character); + ini_set('session.sid_length', $sid_length); + } } + // Yes, 4,5,6 are the only known possible values as of 2016-10-27 switch ($bits_per_character) { case 4: - $this->_sid_regexp = '[0-9a-f]{40,}'; + $this->_sid_regexp = '[0-9a-f]'; break; case 5: - $this->_sid_regexp = '[0-9a-v]{40,}'; + $this->_sid_regexp = '[0-9a-v]'; break; case 6: - $this->_sid_regexp = '[0-9a-zA-Z,-]{40,}'; + $this->_sid_regexp = '[0-9a-zA-Z,-]'; break; } + + $this->_sid_regexp .= '{'.$sid_length.'}'; } // ------------------------------------------------------------------------ -- cgit v1.2.3-24-g4f1b From dbc025b6c2c9b0b085bb79dc126bc58fb2a8c2a8 Mon Sep 17 00:00:00 2001 From: Andrey Andreev Date: Thu, 27 Oct 2016 17:37:25 +0300 Subject: [ci skip] Another attempt at #4874 --- system/libraries/Session/Session.php | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'system/libraries/Session') diff --git a/system/libraries/Session/Session.php b/system/libraries/Session/Session.php index ea7853108..01989d2d7 100644 --- a/system/libraries/Session/Session.php +++ b/system/libraries/Session/Session.php @@ -348,8 +348,9 @@ class CI_Session { if ($hash_function !== '1') { ini_set('session.hash_function', 1); - $bits = 160; } + + $bits = 160; } elseif ( ! in_array($hash_function, hash_algos(), TRUE)) { @@ -363,7 +364,7 @@ class CI_Session { } $bits_per_character = (int) ini_get('session.hash_bits_per_character'); - $sid_length = $bits * $bits_per_character; + $sid_length = (int) ceil($bits / $bits_per_character); } else { -- cgit v1.2.3-24-g4f1b