From f9af8fc912219bb3e0304ba53c81fc5d963009c5 Mon Sep 17 00:00:00 2001 From: Stephen Abello Date: Thu, 12 Mar 2020 14:13:17 +0100 Subject: [PATCH 01/11] =?UTF-8?q?N=C2=B02855=20-=20Security=20hardening?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit (cherry picked from commit c5c7fd5c859f24467d29a057de6f00ae3d9e77e8) --- application/loginwebpage.class.inc.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/application/loginwebpage.class.inc.php b/application/loginwebpage.class.inc.php index e47c35665..38885aa58 100644 --- a/application/loginwebpage.class.inc.php +++ b/application/loginwebpage.class.inc.php @@ -384,7 +384,7 @@ EOF else { // Trash the token and change the password - $oUser->Set('reset_pwd_token', ''); + $oUser->Set('reset_pwd_token', new ormPassword()); $oUser->AllowWrite(true); $oUser->SetPassword($sNewPwd); // Does record the change into the DB From bfcd137e5256727061a99e6fa1085c893e2254c8 Mon Sep 17 00:00:00 2001 From: Stephen Abello Date: Tue, 10 Mar 2020 10:23:38 +0100 Subject: [PATCH 02/11] =?UTF-8?q?N=C2=B02853=20-=20Security=20hardening?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit (cherry picked from commit d01caaf4e47e60736914bc6f38f5e6f485acc0b0) --- application/dashlet.class.inc.php | 50 +++++++++++++++--------------- application/menunode.class.inc.php | 7 +++-- pages/ajax.render.php | 2 +- 3 files changed, 30 insertions(+), 29 deletions(-) diff --git a/application/dashlet.class.inc.php b/application/dashlet.class.inc.php index c62392860..9f99c6324 100644 --- a/application/dashlet.class.inc.php +++ b/application/dashlet.class.inc.php @@ -613,12 +613,12 @@ class DashletUnknown extends Dashlet { $aInfos = static::GetInfo(); - $sIconUrl = utils::GetAbsoluteUrlAppRoot().$aInfos['icon']; + $sIconUrl = utils::HtmlEntities(utils::GetAbsoluteUrlAppRoot().$aInfos['icon']); $sExplainText = ($bEditMode) ? Dict::Format('UI:DashletUnknown:RenderText:Edit', $this->GetDashletType()) : Dict::S('UI:DashletUnknown:RenderText:View'); $oPage->add('
'); - $oPage->add('
'); + $oPage->add('
'); $oPage->add('
'.$sExplainText.'
'); $oPage->add('
'); @@ -633,12 +633,12 @@ class DashletUnknown extends Dashlet { $aInfos = static::GetInfo(); - $sIconUrl = utils::GetAbsoluteUrlAppRoot().$aInfos['icon']; + $sIconUrl = utils::HtmlEntities(utils::GetAbsoluteUrlAppRoot().$aInfos['icon']); $sExplainText = Dict::Format('UI:DashletUnknown:RenderNoDataText:Edit', $this->GetDashletType()); $oPage->add('
'); - $oPage->add('
'); + $oPage->add('
'); $oPage->add('
'.$sExplainText.'
'); $oPage->add('
'); @@ -774,12 +774,12 @@ class DashletProxy extends DashletUnknown { $aInfos = static::GetInfo(); - $sIconUrl = utils::GetAbsoluteUrlAppRoot().$aInfos['icon']; + $sIconUrl = utils::HtmlEntities(utils::GetAbsoluteUrlAppRoot().$aInfos['icon']); $sExplainText = Dict::Format('UI:DashletProxy:RenderNoDataText:Edit', $this->GetDashletType()); $oPage->add('
'); - $oPage->add('
'); + $oPage->add('
'); $oPage->add('
'.$sExplainText.'
'); $oPage->add('
'); @@ -860,7 +860,7 @@ class DashletPlainText extends Dashlet */ public function Render($oPage, $bEditMode = false, $aExtraParams = array()) { - $sText = htmlentities($this->aProperties['text'], ENT_QUOTES, 'UTF-8'); + $sText = utils::HtmlEntities($this->aProperties['text']); $sText = str_replace(array("\r\n", "\n", "\r"), "
", $sText); $sId = 'plaintext_'.($bEditMode? 'edit_' : '').$this->sId; @@ -917,7 +917,7 @@ class DashletObjectList extends Dashlet $sShowMenu = $this->aProperties['menu'] ? '1' : '0'; $oPage->add('
'); - $sHtmlTitle = htmlentities(Dict::S($sTitle), ENT_QUOTES, 'UTF-8'); // done in the itop block + $sHtmlTitle = utils::HtmlEntities(Dict::S($sTitle)); // done in the itop block if ($sHtmlTitle != '') { $oPage->add('

'.$sHtmlTitle.'

'); @@ -956,7 +956,7 @@ class DashletObjectList extends Dashlet $bShowMenu = $this->aProperties['menu']; $oPage->add('
'); - $sHtmlTitle = htmlentities($this->oModelReflection->DictString($sTitle), ENT_QUOTES, 'UTF-8'); // done in the itop block + $sHtmlTitle = utils::HtmlEntities($this->oModelReflection->DictString($sTitle)); // done in the itop block if ($sHtmlTitle != '') { $oPage->add('

'.$sHtmlTitle.'

'); @@ -1249,7 +1249,7 @@ abstract class DashletGroupBy extends Dashlet case 'table': default: - $sHtmlTitle = htmlentities(Dict::S($sTitle), ENT_QUOTES, 'UTF-8'); // done in the itop block + $sHtmlTitle = utils::HtmlEntities(Dict::S($sTitle)); // done in the itop block $sType = 'count'; $aParams = array( 'group_by' => $this->sGroupByExpr, @@ -1686,7 +1686,7 @@ class DashletGroupByPie extends DashletGroupBy $sBlockId = 'block_fake_'.$this->sId.($bEditMode ? '_edit' : ''); // make a unique id (edition occuring in the same DOM) - $HTMLsTitle = ($sTitle != '') ? '

'.htmlentities($sTitle, ENT_QUOTES, 'UTF-8').'

' : ''; + $HTMLsTitle = ($sTitle != '') ? '

'.utils::HtmlEntities($sTitle).'

' : ''; $oPage->add("
$HTMLsTitle
"); $aDisplayValues = $this->MakeSimulatedData(); @@ -1758,7 +1758,7 @@ class DashletGroupByBars extends DashletGroupBy $sBlockId = 'block_fake_'.$this->sId.($bEditMode ? '_edit' : ''); // make a unique id (edition occuring in the same DOM) - $HTMLsTitle = ($sTitle != '') ? '

'.htmlentities($sTitle, ENT_QUOTES, 'UTF-8').'

' : ''; + $HTMLsTitle = ($sTitle != '') ? '

'.utils::HtmlEntities($sTitle).'

' : ''; $oPage->add("
$HTMLsTitle
"); $aDisplayValues = $this->MakeSimulatedData(); @@ -1907,16 +1907,16 @@ class DashletHeaderStatic extends Dashlet */ public function Render($oPage, $bEditMode = false, $aExtraParams = array()) { - $sTitle = $this->aProperties['title']; + $sTitle = utils::HtmlEntities($this->aProperties['title']); $sIcon = $this->aProperties['icon']; $oIconSelect = $this->oModelReflection->GetIconSelectionField('icon'); - $sIconPath = $oIconSelect->MakeFileUrl($sIcon); + $sIconPath = utils::HtmlEntities($oIconSelect->MakeFileUrl($sIcon)); $oPage->add('
'); $oPage->add('
'); - $oPage->add(''); + $oPage->add(''); $oPage->add('

'.$this->oModelReflection->DictString($sTitle).'

'); $oPage->add('
'); @@ -2037,14 +2037,14 @@ class DashletHeaderDynamic extends Dashlet */ public function Render($oPage, $bEditMode = false, $aExtraParams = array()) { - $sTitle = $this->aProperties['title']; + $sTitle = utils::HtmlEntities($this->aProperties['title']); $sIcon = $this->aProperties['icon']; - $sSubtitle = $this->aProperties['subtitle']; + $sSubtitle = utils::HtmlEntities($this->aProperties['subtitle']); $sQuery = $this->aProperties['query']; $sGroupBy = $this->aProperties['group_by']; $oIconSelect = $this->oModelReflection->GetIconSelectionField('icon'); - $sIconPath = $oIconSelect->MakeFileUrl($sIcon); + $sIconPath = utils::HtmlEntities($oIconSelect->MakeFileUrl($sIcon)); $aValues = $this->GetValues(); if (count($aValues) > 0) @@ -2072,7 +2072,7 @@ class DashletHeaderDynamic extends Dashlet $oPage->add('
'); $oPage->add('
'); - $oPage->add(''); + $oPage->add(''); if (isset($aExtraParams['query_params'])) { @@ -2101,9 +2101,9 @@ class DashletHeaderDynamic extends Dashlet */ public function RenderNoData($oPage, $bEditMode = false, $aExtraParams = array()) { - $sTitle = $this->aProperties['title']; + $sTitle = utils::HtmlEntities($this->aProperties['title']); $sIcon = $this->aProperties['icon']; - $sSubtitle = $this->aProperties['subtitle']; + $sSubtitle = utils::HtmlEntities($this->aProperties['subtitle']); $sQuery = $this->aProperties['query']; $sGroupBy = $this->aProperties['group_by']; @@ -2111,12 +2111,12 @@ class DashletHeaderDynamic extends Dashlet $sClass = $oQuery->GetClass(); $oIconSelect = $this->oModelReflection->GetIconSelectionField('icon'); - $sIconPath = $oIconSelect->MakeFileUrl($sIcon); + $sIconPath = utils::HtmlEntities($oIconSelect->MakeFileUrl($sIcon)); $oPage->add('
'); $oPage->add('
'); - $oPage->add(''); + $oPage->add(''); $sBlockId = 'block_fake_'.$this->sId.($bEditMode ? '_edit' : ''); // make a unique id (edition occuring in the same DOM) @@ -2147,8 +2147,8 @@ class DashletHeaderDynamic extends Dashlet $sTitle = $this->oModelReflection->DictString($sTitle); $sSubtitle = $this->oModelReflection->DictFormat($sSubtitle, $iTotal); - $oPage->add('

'.$sTitle.'

'); - $oPage->add(''.$sSubtitle.''); + $oPage->add('

'.utils::HtmlEntities($sTitle).'

'); + $oPage->add(''.utils::HtmlEntities($sSubtitle).''); $oPage->add('
'); $oPage->add('
'); diff --git a/application/menunode.class.inc.php b/application/menunode.class.inc.php index 82bfa09f8..14c50079c 100644 --- a/application/menunode.class.inc.php +++ b/application/menunode.class.inc.php @@ -3,7 +3,7 @@ // // This file is part of iTop. // -// iTop is free software; you can redistribute it and/or modify +// iTop is free software; you can redistribute it and/or modify // it under the terms of the GNU Affero General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. @@ -293,7 +293,8 @@ EOF $sHyperlink = $oMenu->GetHyperlink($aExtraParams); if ($sHyperlink != '') { - $oPage->AddToMenu('
  • '.$oMenu->GetTitle().'
  • '); + $sTitle = utils::HtmlEntities($oMenu->GetTitle()); + $oPage->AddToMenu('
  • '.$sTitle.'
  • '); } else { @@ -905,7 +906,7 @@ class OQLMenuNode extends MenuNode $oBlock->Display($oPage, 0); } - $oPage->add("

    $sIcon ".Dict::S($sTitle)."

    "); + $oPage->add("

    $sIcon ".utils::HtmlEntities(Dict::S($sTitle))."

    "); $aParams = array_merge(array('table_id' => $sUsageId), $aExtraParams); $oBlock = new DisplayBlock($oSearch, 'list', false /* Asynchronous */, $aParams); diff --git a/pages/ajax.render.php b/pages/ajax.render.php index ca05b2310..727abf0d5 100644 --- a/pages/ajax.render.php +++ b/pages/ajax.render.php @@ -1130,7 +1130,7 @@ EOF break; case 'dashboard_editor': - $sId = utils::ReadParam('id', '', false, 'raw_data'); + $sId = utils::ReadParam('id', '', false, 'element_identifier'); $aExtraParams = utils::ReadParam('extra_params', array(), false, 'raw_data'); $sDashboardFile = utils::ReadParam('file', '', false, 'raw_data'); $sReloadURL = utils::ReadParam('reload_url', '', false, 'raw_data'); From 016fbaed3608c7d1cf9e8fdedafd560deedd632c Mon Sep 17 00:00:00 2001 From: Stephen Abello Date: Wed, 12 Feb 2020 14:49:05 +0100 Subject: [PATCH 03/11] =?UTF-8?q?N=C2=B02755=20-=20Security=20hardening?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- pages/csvimport.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pages/csvimport.php b/pages/csvimport.php index 6c2876eb2..3118fe46d 100644 --- a/pages/csvimport.php +++ b/pages/csvimport.php @@ -463,7 +463,7 @@ try // Do nothing } } - $sHtmlValue = $oCellStatus->GetDisplayableValue(); + $sHtmlValue = utils::HtmlEntities(utils::HtmlEntityDecode($oCellStatus->GetDisplayableValue())); switch(get_class($oCellStatus)) { case 'CellStatus_Issue': From 4b7f736af0f8b2cf2f5803cf135306958eef9905 Mon Sep 17 00:00:00 2001 From: Stephen Abello Date: Thu, 6 Feb 2020 14:50:27 +0100 Subject: [PATCH 04/11] =?UTF-8?q?N=C2=B02755=20-=20Security=20hardening?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- pages/ajax.csvimport.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pages/ajax.csvimport.php b/pages/ajax.csvimport.php index df95b721f..8468c92b2 100644 --- a/pages/ajax.csvimport.php +++ b/pages/ajax.csvimport.php @@ -366,7 +366,7 @@ try $sDefaultChoice = $aInitFieldMapping[$index]; } $oPage->add(''); - $oPage->add("$sField"); + $oPage->add(''.utils::HtmlEntities($sField).''); $oPage->add(''.GetMappingForField($sClassName, $sField, $index, $bAdvanced, $sDefaultChoice).''); $oPage->add(' '); $oPage->add(''); From 6edc365685d1d8a9234f40f40e7d7879fc4d6ea9 Mon Sep 17 00:00:00 2001 From: Stephen Abello Date: Thu, 6 Feb 2020 14:27:13 +0100 Subject: [PATCH 05/11] =?UTF-8?q?N=C2=B02742=20-=20HTML=20files=20preview?= =?UTF-8?q?=20are=20now=20raw=20text=20only?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- application/cmdbabstract.class.inc.php | 1 - 1 file changed, 1 deletion(-) diff --git a/application/cmdbabstract.class.inc.php b/application/cmdbabstract.class.inc.php index bc0fcbb4f..f5a97f920 100644 --- a/application/cmdbabstract.class.inc.php +++ b/application/cmdbabstract.class.inc.php @@ -2966,7 +2966,6 @@ EOF $data = $oDoc->GetData(); switch ($oDoc->GetMimeType()) { - case 'text/html': case 'text/xml': $oPage->add("\n"); break; From a3a34a94e722cefc10a133970323617c745384e3 Mon Sep 17 00:00:00 2001 From: Eric Date: Mon, 6 Apr 2020 11:47:57 +0200 Subject: [PATCH 06/11] =?UTF-8?q?N=C2=B01355=20-=20Security=20hardening?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- application/loginwebpage.class.inc.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/application/loginwebpage.class.inc.php b/application/loginwebpage.class.inc.php index 38885aa58..424d1231d 100644 --- a/application/loginwebpage.class.inc.php +++ b/application/loginwebpage.class.inc.php @@ -156,7 +156,7 @@ class LoginWebPage extends NiceWebPage $this->add("\n"); $sForgotPwd = $this->EnableResetPassword() ? $this->ForgotPwdLink() : ''; $this->add("\n"); - $this->add("\n"); + $this->add("\n"); $this->add("\n"); if (strlen($sForgotPwd) > 0) { From b1d703bff3e33c37e39579587f6040bbd92b4e8b Mon Sep 17 00:00:00 2001 From: Eric Date: Mon, 6 Apr 2020 14:07:42 +0200 Subject: [PATCH 07/11] =?UTF-8?q?N=C2=B01671=20Portal:=20Fix=20Aggregate?= =?UTF-8?q?=20Brick=20when=20user=20profile=20is=20not=20allowed=20to=20se?= =?UTF-8?q?e=20one=20of=20the=20sub-brick?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../controllers/aggregatepagebrickcontroller.class.inc.php | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/datamodels/2.x/itop-portal-base/portal/src/controllers/aggregatepagebrickcontroller.class.inc.php b/datamodels/2.x/itop-portal-base/portal/src/controllers/aggregatepagebrickcontroller.class.inc.php index b9379f8df..fe6658cd2 100644 --- a/datamodels/2.x/itop-portal-base/portal/src/controllers/aggregatepagebrickcontroller.class.inc.php +++ b/datamodels/2.x/itop-portal-base/portal/src/controllers/aggregatepagebrickcontroller.class.inc.php @@ -21,6 +21,7 @@ namespace Combodo\iTop\Portal\Controller; use Combodo\iTop\Portal\Helper\ApplicationHelper; +use IssueLog; use Silex\Application; use Symfony\Component\HttpFoundation\Request; @@ -81,7 +82,8 @@ class AggregatePageBrickController $oPortalBrick = $this->GetBrickFromId($aPortalInstanceBricks, $sBrickId); if (!isset($oPortalBrick)) { - throw new \Exception("AggregatePageBrick : non existing brick '$sBrickId'"); + IssueLog::Warning('AggregatePageBrick: Could not display "'.$sBrickId.'", either wrong id or user profile not allowed'); + continue; } $aAggregatePageBricks[] = $oPortalBrick; } @@ -144,4 +146,4 @@ class AggregatePageBrickController return $aTilesRendering; } -} \ No newline at end of file +} From 3a37e244962269fa7dd917c4d1fa4156fe09b817 Mon Sep 17 00:00:00 2001 From: Eric Date: Wed, 8 Apr 2020 09:28:20 +0200 Subject: [PATCH 08/11] =?UTF-8?q?N=C2=B02306=20-=20Security=20hardening?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../userprofilebrickcontroller.class.inc.php | 18 +++++++++--------- .../bricks/manage/popup-export-excel.html.twig | 2 +- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/datamodels/2.x/itop-portal-base/portal/src/controllers/userprofilebrickcontroller.class.inc.php b/datamodels/2.x/itop-portal-base/portal/src/controllers/userprofilebrickcontroller.class.inc.php index 8a3daeb30..16707297d 100644 --- a/datamodels/2.x/itop-portal-base/portal/src/controllers/userprofilebrickcontroller.class.inc.php +++ b/datamodels/2.x/itop-portal-base/portal/src/controllers/userprofilebrickcontroller.class.inc.php @@ -19,19 +19,19 @@ namespace Combodo\iTop\Portal\Controller; +use Combodo\iTop\Portal\Brick\UserProfileBrick; +use Combodo\iTop\Portal\Form\PasswordFormManager; +use Combodo\iTop\Portal\Form\PreferencesFormManager; +use Combodo\iTop\Portal\Helper\ApplicationHelper; +use Combodo\iTop\Renderer\Bootstrap\BsFormRenderer; use Exception; use FileUploadException; use IssueLog; -use utils; use MetaModel; -use UserRights; use Silex\Application; use Symfony\Component\HttpFoundation\Request; -use Combodo\iTop\Portal\Helper\ApplicationHelper; -use Combodo\iTop\Portal\Brick\UserProfileBrick; -use Combodo\iTop\Portal\Form\PreferencesFormManager; -use Combodo\iTop\Portal\Form\PasswordFormManager; -use Combodo\iTop\Renderer\Bootstrap\BsFormRenderer; +use UserRights; +use utils; /** * Class UserProfileBrickController @@ -159,7 +159,7 @@ class UserProfileBrickController extends BrickController { // - Creating renderer $oFormRenderer = new BsFormRenderer(); - $oFormRenderer->SetEndpoint($_SERVER['REQUEST_URI']); + $oFormRenderer->SetEndpoint($oApp['url_generator']->generate('p_user_profile_brick')); // - Creating manager $oFormManager = new PreferencesFormManager(); $oFormManager->SetRenderer($oFormRenderer) @@ -232,7 +232,7 @@ class UserProfileBrickController extends BrickController { // - Creating renderer $oFormRenderer = new BsFormRenderer(); - $oFormRenderer->SetEndpoint($_SERVER['REQUEST_URI']); + $oFormRenderer->SetEndpoint($oApp['url_generator']->generate('p_user_profile_brick')); // - Creating manager $oFormManager = new PasswordFormManager(); $oFormManager->SetRenderer($oFormRenderer) diff --git a/datamodels/2.x/itop-portal-base/portal/src/views/bricks/manage/popup-export-excel.html.twig b/datamodels/2.x/itop-portal-base/portal/src/views/bricks/manage/popup-export-excel.html.twig index a6922d0ff..4194af16c 100644 --- a/datamodels/2.x/itop-portal-base/portal/src/views/bricks/manage/popup-export-excel.html.twig +++ b/datamodels/2.x/itop-portal-base/portal/src/views/bricks/manage/popup-export-excel.html.twig @@ -27,7 +27,7 @@