Skip to content
Permalink
Browse files Browse the repository at this point in the history
N°3952 - code hardening
  • Loading branch information
eespie committed May 27, 2021
1 parent db6e813 commit 43daa2e
Show file tree
Hide file tree
Showing 5 changed files with 91 additions and 27 deletions.
10 changes: 2 additions & 8 deletions setup/ajax.dataloader.php
Expand Up @@ -147,12 +147,7 @@ function FatalErrorCatcher($sOutput)
$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)
{
Expand Down Expand Up @@ -199,15 +194,14 @@ function FatalErrorCatcher($sOutput)
{
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);
}

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
{
Expand Down
19 changes: 13 additions & 6 deletions setup/index.php
Expand Up @@ -30,6 +30,7 @@
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')));
Expand All @@ -41,21 +42,27 @@
/////////////////////////////////////////////////////////////////////
// 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();
}
}
/////////////////////////////////////////////////////////////////////

$oWizard = new WizardController('WizStepWelcome');
$oWizard->Run();
//N°3952
if (SetupUtils::IsSessionSetupTokenValid()) {
// Normal operation
$oWizard->Run();
} else {
// Force initializing the setup
$oWizard->Start();
SetupUtils::CreateSetupToken();
}
69 changes: 69 additions & 0 deletions setup/setuputils.class.inc.php
Expand Up @@ -1826,6 +1826,75 @@ static public function GetSetupQueriesFilePath()
{
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']);
}
}

/**
Expand Down
8 changes: 5 additions & 3 deletions setup/wizardcontroller.class.inc.php
Expand Up @@ -105,7 +105,7 @@ public function SaveParameter($sParamCode, $defaultValue, $sSanitizationFilter =
/**
* 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);
Expand All @@ -121,7 +121,7 @@ protected function Next()
$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();
Expand Down Expand Up @@ -173,14 +173,16 @@ protected function DisplayStep(WizardStep $oStep)
// 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");
$oP->error("<b>Error:</b> the configuration file '".$sRelativePath."' already exists and cannot be overwritten.");
$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;
}
}
}
Expand Down
12 changes: 2 additions & 10 deletions setup/wizardsteps.class.inc.php
Expand Up @@ -57,16 +57,7 @@ public function GetPossibleSteps()

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' => '');
}
Expand Down Expand Up @@ -2643,6 +2634,7 @@ public function Display(WebPage $oPage)
$oPage->add('<img style="border:0" src="'.$sImgUrl.'"/>');
$sForm = addslashes($sForm);
$oPage->add_ready_script("$('#wiz_form').after('$sForm');");
SetupUtils::EraseSetupToken();
}

public function CanMoveForward()
Expand Down

0 comments on commit 43daa2e

Please sign in to comment.