do NOT store DB password in session: DB class now stores it in (shared memory) cache instead

on session-restore we check if the DB-password is available from cache, if not we re-create egw_info and egw object
This commit is contained in:
ralf 2025-02-13 14:46:39 +01:00
parent 13e5e69676
commit ddc556a5b3
4 changed files with 35 additions and 11 deletions

View File

@ -622,7 +622,14 @@ class Db
*/
function __wakeup()
{
$this->connect(); // we need to re-connect
// we need to re-connect
$this->connect(null, null, null, null,
// get DB password again from instance-cache, as we don't store it in session
Cache::getInstance(__CLASS__, 'Password') ?:
// check if header is still available
$GLOBALS['egw_domain'][$GLOBALS['egw_info']['user']['domain']]['db_password'] ??
// as last resort, redirect to login
Framework::redirect_link('/login.php?cd=2'));
}
/**
@ -638,7 +645,9 @@ class Db
if (!empty($this->setupType)) $this->Type = $this->setupType; // restore Type eg. to mysqli
$vars = get_object_vars($this);
unset($vars['Link_ID'], $vars['Query_ID'], $vars['privat_Link_ID']);
// don't store DB password in session, just in (shared memory) instance-cache
Cache::setInstance(__CLASS__, 'Password', $vars['Password'], 86400);
unset($vars['Link_ID'], $vars['Query_ID'], $vars['privat_Link_ID'], $vars['Password']);
return array_keys($vars);
}

View File

@ -192,7 +192,7 @@ abstract class Framework extends Framework\Extra
static function link($url, $extravars = '', $link_app=null)
{
unset($link_app); // not used by required by function signature
return $GLOBALS['egw']->session->link($url, $extravars);
return Session::link($url, $extravars);
}
/**

View File

@ -155,13 +155,21 @@ class Updates
return Cache::getTree(__CLASS__, 'api_version', function()
{
$version = preg_replace('/[^0-9.]/', '', $GLOBALS['egw_info']['server']['versions']['api']);
if (!isset($GLOBALS['egw_info']['server']['versions']))
{
$GLOBALS['egw_info']['server']['versions'] = [];
}
else
{
$version = preg_replace('/[^0-9.]/', '', $GLOBALS['egw_info']['server']['versions']['api']);
}
if (empty($GLOBALS['egw_info']['server']['versions']['maintenance_release']))
{
$setup_info = null;
include (EGW_SERVER_ROOT.'/api/setup/setup.inc.php');
$GLOBALS['egw_info']['server']['versions'] += $setup_info['api']['versions'];
$version = $version ?? $setup_info['api']['version'];
unset($setup_info);
}
if (version_compare($version, $GLOBALS['egw_info']['server']['versions']['maintenance_release'], '<'))
@ -171,4 +179,4 @@ class Updates
return $version;
}, array(), 300);
}
}
}

View File

@ -18,6 +18,7 @@
use EGroupware\Api\Session;
use EGroupware\Api\Egw;
use EGroupware\Api;
// E_STRICT in PHP 5.4 gives various strict warnings in working code, which can NOT be easy fixed in all use-cases :-(
// Only variables should be assigned by reference, eg. soetemplate::tree_walk()
@ -64,14 +65,18 @@ if (Session::init_handler())
// restoring the egw_info-array
$GLOBALS['egw_info'] = array_merge($_SESSION[Session::EGW_INFO_CACHE],array('flags' => $GLOBALS['egw_info']['flags']));
$GLOBALS['egw'] = unserialize($_SESSION[Session::EGW_OBJECT_CACHE], ['allowed_classes' => true]);
if (is_object($GLOBALS['egw']) && ($GLOBALS['egw'] instanceof Egw)) // only egw object has wakeup2, setups egw_minimal eg. has not!
// check if we have a DB-password in cache, if not restore the session via the header (happens when kill -s USR2 1 is used to restart FPM)
if (Api\Cache::getInstance(Api\Db::class, 'Password'))
{
$GLOBALS['egw']->wakeup2(); // adapt the restored egw-object/environment to this request (eg. changed current app)
$GLOBALS['egw'] = unserialize($_SESSION[Session::EGW_OBJECT_CACHE], ['allowed_classes' => true]);
$GLOBALS['egw_info']['flags']['session_restore_time'] = microtime(true) - $GLOBALS['egw_info']['flags']['page_start_time'];
if (is_object($GLOBALS['egw']->translation)) return; // exit this file, as the rest of the file creates a new egw-object and -enviroment
if (is_object($GLOBALS['egw']) && ($GLOBALS['egw'] instanceof Egw)) // only egw object has wakeup2, setups egw_minimal eg. has not!
{
$GLOBALS['egw']->wakeup2(); // adapt the restored egw-object/environment to this request (eg. changed current app)
$GLOBALS['egw_info']['flags']['session_restore_time'] = microtime(true) - $GLOBALS['egw_info']['flags']['page_start_time'];
if (is_object($GLOBALS['egw']->translation)) return; // exit this file, as the rest of the file creates a new egw-object and -environment
}
}
// egw object could NOT be restored from the session, create a new one
unset($GLOBALS['egw']);
@ -101,6 +106,8 @@ $GLOBALS['egw_info']['server'] += $GLOBALS['egw_domain'][$GLOBALS['egw_info']['u
// the egw-object instantiates all sub-classes (eg. $GLOBALS['egw']->db) and the egw_info array
$GLOBALS['egw'] = new Egw(array_keys($GLOBALS['egw_domain']));
// do NOT store the DB-password in the session or egw_info, but let DB connect first (and store the password)
unset($GLOBALS['egw_info']['server']['db_pass']);
if ($GLOBALS['egw_info']['flags']['currentapp'] != 'login' && !$GLOBALS['egw_info']['server']['show_domain_selectbox'])
{