diff options
Diffstat (limited to 'system/libraries/Session.php')
-rw-r--r-- | system/libraries/Session.php | 65 |
1 files changed, 35 insertions, 30 deletions
diff --git a/system/libraries/Session.php b/system/libraries/Session.php index 328438653..64c06f4f1 100644 --- a/system/libraries/Session.php +++ b/system/libraries/Session.php @@ -6,7 +6,7 @@ * * @package CodeIgniter * @author ExpressionEngine Dev Team - * @copyright Copyright (c) 2008 - 2011, EllisLab, Inc. + * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. * @license http://codeigniter.com/user_guide/license.html * @link http://codeigniter.com * @since Version 1.0 @@ -144,31 +144,36 @@ class CI_Session { return FALSE; } - // Decrypt the cookie data - if ($this->sess_encrypt_cookie == TRUE) + // HMAC authentication + if (($len = strlen($session) - 40) <= 0) { - $session = $this->CI->encrypt->decode($session); + log_message('error', 'Session: The session cookie was not signed.'); + return FALSE; } - else + + // Check cookie authentication + $hmac = substr($session, $len); + $session = substr($session, 0, $len); + + // Time-attack-safe comparison + $hmac_check = hash_hmac('sha1', $session, $this->encryption_key); + $diff = 0; + for ($i = 0; $i < 40; $i++) { - // encryption was not used, so we need to check the md5 hash - $hash = substr($session, strlen($session)-32); // get last 32 chars - $session = substr($session, 0, strlen($session)-32); - $hash_check = md5($session.$this->encryption_key); + $diff |= ord($hmac[$i]) ^ ord($hmac_check[$i]); + } - $diff = 0; - for ($i = 0; $i < 32; $i++) - { - $diff |= ord($hash[$i]) ^ ord($hash_check[$i]); - } + if ($diff !== 0) + { + log_message('error', 'Session: HMAC mismatch. The session cookie data did not match what was expected.'); + $this->sess_destroy(); + return FALSE; + } - // Does the md5 hash match? This is to prevent manipulation of session data in userspace - if ($diff !== 0) - { - log_message('error', 'The session cookie data did not match what was expected. This could be a possible hacking attempt.'); - $this->sess_destroy(); - return FALSE; - } + // Decrypt the cookie data + if ($this->sess_encrypt_cookie == TRUE) + { + $session = $this->CI->encrypt->decode($session); } // Unserialize the session array @@ -666,20 +671,20 @@ class CI_Session { else { // if encryption is not used, we provide an md5 hash to prevent userside tampering - $cookie_data = $cookie_data.md5($cookie_data.$this->encryption_key); + $cookie_data .= hash_hmac('sha1', $cookie_data, $this->encryption_key); } $expire = ($this->sess_expire_on_close === TRUE) ? 0 : $this->sess_expiration + time(); // Set the cookie setcookie( - $this->sess_cookie_name, - $cookie_data, - $expire, - $this->cookie_path, - $this->cookie_domain, - $this->cookie_secure - ); + $this->sess_cookie_name, + $cookie_data, + $expire, + $this->cookie_path, + $this->cookie_domain, + $this->cookie_secure + ); } // -------------------------------------------------------------------- @@ -784,4 +789,4 @@ class CI_Session { // END Session Class /* End of file Session.php */ -/* Location: ./system/libraries/Session.php */
\ No newline at end of file +/* Location: ./system/libraries/Session.php */ |