From 7cba81de271d62bdf93ded7598709702a96f92d7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michal=20=C4=8Ciha=C5=99?= Date: Thu, 12 Jun 2014 09:41:27 +0200 Subject: [PATCH] Regenerate cookie encryption IV for every session MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The IV for cookie encryption was generated just once for every browser and kept in a cookie. Generating it for every session is much better to avoid information leaks (eg. that same user has logged in). Signed-off-by: Michal Čihař --- ChangeLog | 1 + .../auth/AuthenticationCookie.class.php | 76 +++++++++++-------- 2 files changed, 44 insertions(+), 33 deletions(-) diff --git a/ChangeLog b/ChangeLog index c98b006de8..52207aafcb 100644 --- a/ChangeLog +++ b/ChangeLog @@ -6,6 +6,7 @@ phpMyAdmin - ChangeLog - bug #4442 New lines are added to query every time - bug #4445 Fatal error on SQL Export of join query - bug #4448 Dump binary columns in hexadecimal notation not working +- Regenerate cookie encryption IV for every session 4.2.3.0 (2014-06-08) - bug #4423 Moving fields not working diff --git a/libraries/plugins/auth/AuthenticationCookie.class.php b/libraries/plugins/auth/AuthenticationCookie.class.php index a2f20ce7d6..fc97362c25 100644 --- a/libraries/plugins/auth/AuthenticationCookie.class.php +++ b/libraries/plugins/auth/AuthenticationCookie.class.php @@ -28,28 +28,6 @@ if (! empty($_REQUEST['target'])) { */ require './libraries/plugins/auth/swekey/swekey.auth.lib.php'; -/** - * Initialization - * Store the initialization vector because it will be needed for - * further decryption. I don't think necessary to have one iv - * per server so I don't put the server number in the cookie name. - */ -if (function_exists('mcrypt_encrypt')) { - if (empty($_COOKIE['pma_mcrypt_iv']) - || ! ($iv = base64_decode($_COOKIE['pma_mcrypt_iv'], true)) - ) { - $td = mcrypt_module_open(MCRYPT_BLOWFISH, '', MCRYPT_MODE_CBC, ''); - if ($td === false) { - PMA_fatalError(__('Failed to use Blowfish from mcrypt!')); - } - $iv = mcrypt_create_iv(mcrypt_enc_get_iv_size($td), MCRYPT_DEV_URANDOM); - $GLOBALS['PMA_Config']->setCookie( - 'pma_mcrypt_iv', - base64_encode($iv) - ); - } -} - /** * Handles the cookie authentication method * @@ -57,6 +35,11 @@ if (function_exists('mcrypt_encrypt')) { */ class AuthenticationCookie extends AuthenticationPlugin { + /** + * IV for Blowfish. + */ + private $_blowfish_iv = null; + /** * Displays authentication form * @@ -462,8 +445,11 @@ class AuthenticationCookie extends AuthenticationPlugin = $_COOKIE['pmaServer-' . $GLOBALS['server']]; } - // username - if (empty($_COOKIE['pmaUser-' . $GLOBALS['server']])) { + // check cookies + if (empty($_COOKIE['pmaUser-' . $GLOBALS['server']]) + || empty($_COOKIE['pmaPass-' . $GLOBALS['server']]) + || empty($_COOKIE['pma_mcrypt_iv']) + ) { return false; } @@ -495,11 +481,6 @@ class AuthenticationCookie extends AuthenticationPlugin } } - // password - if (empty($_COOKIE['pmaPass-' . $GLOBALS['server']])) { - return false; - } - $GLOBALS['PHP_AUTH_PW'] = $this->blowfishDecrypt( $_COOKIE['pmaPass-' . $GLOBALS['server']], $this->_getBlowfishSecret() @@ -570,6 +551,8 @@ class AuthenticationCookie extends AuthenticationPlugin $_SESSION['last_access_time'] = time(); + $this->createBlowfishIV(); + // Name and password cookies need to be refreshed each time // Duration = one month for username $GLOBALS['PMA_Config']->setCookie( @@ -724,7 +707,6 @@ class AuthenticationCookie extends AuthenticationPlugin */ public function blowfishEncrypt($data, $secret) { - global $iv; if (! function_exists('mcrypt_encrypt')) { /** * This library uses mcrypt when available, so @@ -743,7 +725,7 @@ class AuthenticationCookie extends AuthenticationPlugin $secret, $data, MCRYPT_MODE_CBC, - $iv + $this->_blowfish_iv ) ); } @@ -760,7 +742,9 @@ class AuthenticationCookie extends AuthenticationPlugin */ public function blowfishDecrypt($encdata, $secret) { - global $iv; + if (is_null($this->_blowfish_iv)) { + $this->_blowfish_iv = base64_decode($_COOKIE['pma_mcrypt_iv'], true); + } if (! function_exists('mcrypt_encrypt')) { include_once "./libraries/phpseclib/Crypt/AES.php"; $cipher = new Crypt_AES(CRYPT_AES_MODE_ECB); @@ -773,12 +757,38 @@ class AuthenticationCookie extends AuthenticationPlugin $secret, $data, MCRYPT_MODE_CBC, - $iv + $this->_blowfish_iv ); return trim($decrypted); } } + /** + * Initialization + * Store the initialization vector because it will be needed for + * further decryption. I don't think necessary to have one iv + * per server so I don't put the server number in the cookie name. + * + * @return void + */ + public function createBlowfishIV() + { + if (function_exists('mcrypt_encrypt')) { + $td = mcrypt_module_open(MCRYPT_BLOWFISH, '', MCRYPT_MODE_CBC, ''); + if ($td === false) { + PMA_fatalError(__('Failed to use Blowfish from mcrypt!')); + } + $this->_blowfish_iv = mcrypt_create_iv( + mcrypt_enc_get_iv_size($td), + MCRYPT_DEV_URANDOM + ); + $GLOBALS['PMA_Config']->setCookie( + 'pma_mcrypt_iv', + base64_encode($this->_blowfish_iv) + ); + } + } + /** * This method is called when any PluginManager to which the observer * is attached calls PluginManager::notify()