Regenerate cookie encryption IV for every session

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ř <michal@cihar.com>
This commit is contained in:
Michal Čihař 2014-06-12 09:41:27 +02:00
parent b252cb9981
commit 7cba81de27
2 changed files with 44 additions and 33 deletions

View File

@ -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

View File

@ -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()