N°3952 - code hardening

This commit is contained in:
Eric
2021-05-27 09:29:50 +02:00
parent db6e813cba
commit 43daa2ef08
5 changed files with 91 additions and 27 deletions

View File

@@ -147,12 +147,7 @@ header("Expires: Fri, 17 Jul 1970 05:00:00 GMT"); // Date in the past
$sOperation = Utils::ReadParam('operation', '');
try
{
$sAuthent = utils::ReadParam('authent', '', false, 'raw_data');
if (!file_exists(APPROOT.'data/setup/authent') || $sAuthent !== file_get_contents(APPROOT.'data/setup/authent'))
{
throw new SecurityException('Setup operations are not allowed outside of the setup');
SetupPage::log_error("Setup operations are not allowed outside of the setup");
}
SetupUtils::CheckSetupToken();
switch($sOperation)
{
@@ -199,7 +194,6 @@ catch(Exception $e)
{
header("HTTP/1.0 500 Internal server error.");
echo "<p>An error happened while processing the installation:</p>\n";
echo '<p>'.$e."</p>\n";
SetupPage::log_error("An error happened while processing the installation: ".$e);
}
@@ -207,7 +201,7 @@ if (function_exists('memory_get_peak_usage'))
{
if ($sOperation == 'file')
{
SetupPage::log_info("loading file '$sFileName', peak memory usage. ".memory_get_peak_usage());
SetupPage::log_info("loading file peak memory usage. ".memory_get_peak_usage());
}
else
{

View File

@@ -30,6 +30,7 @@ require_once(APPROOT.'/setup/setuppage.class.inc.php');
require_once(APPROOT.'/setup/wizardcontroller.class.inc.php');
require_once(APPROOT.'/setup/wizardsteps.class.inc.php');
session_start();
clearstatcache(); // Make sure we know what we are doing !
// Set a long (at least 4 minutes) execution time for the setup to avoid timeouts during this phase
ini_set('max_execution_time', max(240, ini_get('max_execution_time')));
@@ -41,16 +42,14 @@ date_default_timezone_set('Europe/Paris'); // Just to avoid a warning if the tim
/////////////////////////////////////////////////////////////////////
// Fake functions to protect the first run of the installer
// in case the PHP JSON module is not installed...
if (!function_exists('json_encode'))
{
if (!function_exists('json_encode')) {
function json_encode($value, $options = null)
{
return '[]';
}
}
if (!function_exists('json_decode'))
{
function json_decode($json, $assoc=null)
if (!function_exists('json_decode')) {
function json_decode($json, $assoc = null)
{
return array();
}
@@ -58,4 +57,12 @@ if (!function_exists('json_decode'))
/////////////////////////////////////////////////////////////////////
$oWizard = new WizardController('WizStepWelcome');
$oWizard->Run();
//N°3952
if (SetupUtils::IsSessionSetupTokenValid()) {
// Normal operation
$oWizard->Run();
} else {
// Force initializing the setup
$oWizard->Start();
SetupUtils::CreateSetupToken();
}

View File

@@ -1826,6 +1826,75 @@ EOF
{
return APPROOT.'log/setup-queries-'.strftime('%Y-%m-%d_%H_%M').'.sql';
}
/**
* Create and store Setup authentication token
*
* @return string token
*/
public final static function CreateSetupToken()
{
if (!is_dir(APPROOT.'data'))
{
mkdir(APPROOT.'data');
}
if (!is_dir(APPROOT.'data/setup'))
{
mkdir(APPROOT.'data/setup');
}
$sUID = hash('sha256', rand());
file_put_contents(APPROOT.'data/setup/authent', $sUID);
$_SESSION['setup_token'] = $sUID;
return $sUID;
}
/**
* Verify Setup authentication token (from the request parameter 'authent')
*
* @param bool $bRemoveToken
*
* @throws \SecurityException
*/
public final static function CheckSetupToken($bRemoveToken = false)
{
$sAuthent = utils::ReadParam('authent', '', false, 'raw_data');
$sTokenFile = APPROOT.'data/setup/authent';
if (!file_exists($sTokenFile) || $sAuthent !== file_get_contents($sTokenFile))
{
throw new SecurityException('Setup operations are not allowed outside of the setup');
}
if ($bRemoveToken)
{
@unlink($sTokenFile);
}
}
/**
* Check setup transaction and create a new one if necessary
*
* @return bool
*/
public static function IsSessionSetupTokenValid()
{
if (isset($_SESSION['setup_token'])) {
$sAuth = $_SESSION['setup_token'];
$sTokenFile = APPROOT.'data/setup/authent';
if (file_exists($sTokenFile) && $sAuth === file_get_contents($sTokenFile)) {
return true;
}
}
return false;
}
public static function EraseSetupToken()
{
$sTokenFile = APPROOT.'data/setup/authent';
if (is_file($sTokenFile)) {
unlink($sTokenFile);
}
unset($_SESSION['setup_token']);
}
}
/**

View File

@@ -105,7 +105,7 @@ class WizardController
/**
* Starts the wizard by displaying it in its initial state
*/
protected function Start()
public function Start()
{
$sCurrentStepClass = $this->sInitialStepClass;
$oStep = new $sCurrentStepClass($this, $this->sInitialState);
@@ -121,7 +121,7 @@ class WizardController
$sCurrentState = utils::ReadParam('_state', $this->sInitialState);
/** @var \WizardStep $oStep */
$oStep = new $sCurrentStepClass($this, $sCurrentState);
if ($oStep->ValidateParams($sCurrentState))
if ($oStep->ValidateParams())
{
$this->PushStep(array('class' => $sCurrentStepClass, 'state' => $sCurrentState));
$aPossibleSteps = $oStep->GetPossibleSteps();
@@ -173,6 +173,7 @@ class WizardController
// The configuration file already exists
if (!is_writable($sConfigFile))
{
SetupUtils::EraseSetupToken();
$sRelativePath = utils::GetConfigFilePathRelative();
$oP = new SetupPage('Installation Cannot Continue');
$oP->add("<h2>Fatal error</h2>\n");
@@ -180,7 +181,8 @@ class WizardController
$oP->p("The wizard cannot modify the configuration file for you. If you want to upgrade ".ITOP_APPLICATION.", make sure that the file '<b>".$sRelativePath."</b>' can be modified by the web server.");
$oP->p('<button type="button" onclick="window.location.reload()">Reload</button>');
$oP->output();
return;
// Prevent token creation
exit;
}
}
}

View File

@@ -57,16 +57,7 @@ class WizStepWelcome extends WizardStep
public function ProcessParams($bMoveForward = true)
{
if (!is_dir(APPROOT.'data'))
{
mkdir(APPROOT.'data');
}
if (!is_dir(APPROOT.'data/setup'))
{
mkdir(APPROOT.'data/setup');
}
$sUID = hash('sha256', rand());
file_put_contents(APPROOT.'data/setup/authent', $sUID);
$sUID = SetupUtils::CreateSetupToken();
$this->oWizard->SetParameter('authent', $sUID);
return array('class' => 'WizStepInstallOrUpgrade', 'state' => '');
}
@@ -2643,6 +2634,7 @@ class WizStepDone extends WizardStep
$oPage->add('<img style="border:0" src="'.$sImgUrl.'"/>');
$sForm = addslashes($sForm);
$oPage->add_ready_script("$('#wiz_form').after('$sForm');");
SetupUtils::EraseSetupToken();
}
public function CanMoveForward()