From cf0541c93e9b1b63d3fe4aec56addb450b998a34 Mon Sep 17 00:00:00 2001 From: Denis Flaven Date: Thu, 11 Feb 2016 10:22:53 +0000 Subject: [PATCH] #1202: Fix for a security vulnerability in the Configuration Editor. SVN:trunk[3902] --- datamodels/2.x/itop-config/config.php | 56 ++++++++++++++++++++------- 1 file changed, 42 insertions(+), 14 deletions(-) diff --git a/datamodels/2.x/itop-config/config.php b/datamodels/2.x/itop-config/config.php index f2bf931a1..4e04a3c5a 100644 --- a/datamodels/2.x/itop-config/config.php +++ b/datamodels/2.x/itop-config/config.php @@ -1,5 +1,5 @@ add("
Sorry, iTop is in demonstration mode: the configuration file cannot be edited.
"); } + if (MetaModel::GetModuleSetting('itop-config', 'config_editor', '') == 'disabled') + { + $oP->add("
iTop interactive edition of the configuration as been disabled. See 'config_editor' => 'disabled' in the configuration file.
"); + } else { $oP->add_style( @@ -129,27 +133,50 @@ EOF if ($sOperation == 'save') { $sConfig = utils::ReadParam('new_config', '', false, 'raw_data'); + $sTransactionId = utils::ReadParam('transaction_id', ''); $sOrginalConfig = utils::ReadParam('prev_config', '', false, 'raw_data'); - if ($sConfig == $sOrginalConfig) + if (!utils::IsTransactionValid($sTransactionId, true)) { - $oP->add('
'.Dict::S('config-no-change').'
'); + $oP->add("
Error: invalid Transaction ID. The configuration was NOT modified.
"); } else { - try + if ($sConfig == $sOrginalConfig) { - TestConfig($sConfig, $oP); // throws exceptions - - @chmod($sConfigFile, 0770); // Allow overwriting the file - file_put_contents($sConfigFile, $sConfig); - @chmod($sConfigFile, 0444); // Read-only - - $oP->p('
'.Dict::S('Successfully recorded.').'
'); - $sOrginalConfig = str_replace("\r\n", "\n", file_get_contents($sConfigFile)); + $oP->add('
'.Dict::S('config-no-change').'
'); } - catch (Exception $e) + else { - $oP->p('
'.$e->getMessage().'
'); + try + { + TestConfig($sConfig, $oP); // throws exceptions + + @chmod($sConfigFile, 0770); // Allow overwriting the file + $sTmpFile = tempnam(SetupUtils::GetTmpDir(), 'itop-cfg-'); + // Don't write the file as-is since it would allow to inject any kind of PHP code. + // Instead write the interpreted version of the file + // Note: + // The actual raw PHP code will anyhow be interpreted exactly twice: once in TestConfig() above + // and a second time during the load of the Config object below. + // If you are really concerned about an iTop administrator crafting some malicious + // PHP code inside the config file, then turn off the interactive configuration + // editor by adding the configuration parameter: + // 'itop-config' => array( + // 'config_editor' => 'disabled', + // ) + file_put_contents($sTmpFile, $sConfig); + $oTempConfig = new Config($sTmpFile, true); + $oTempConfig->WriteToFile($sConfigFile); + @unlink($sTmpFile); + @chmod($sConfigFile, 0444); // Read-only + + $oP->p('
'.Dict::S('Successfully recorded.').'
'); + $sOrginalConfig = str_replace("\r\n", "\n", file_get_contents($sConfigFile)); + } + catch (Exception $e) + { + $oP->p('
'.$e->getMessage().'
'); + } } } } @@ -164,6 +191,7 @@ EOF $oP->p(Dict::S('config-edit-intro')); $oP->add("
"); $oP->add(""); + $oP->add(""); $oP->add(""); $oP->add("".Dict::Format('config-current-line', "").""); $oP->add("");