diff --git a/application/loginwebpage.class.inc.php b/application/loginwebpage.class.inc.php index f7cf9ce79..57a577eec 100644 --- a/application/loginwebpage.class.inc.php +++ b/application/loginwebpage.class.inc.php @@ -90,7 +90,7 @@ class LoginWebPage extends NiceWebPage parent::__construct($sTitle); $this->SetStyleSheet(); $this->no_cache(); - $this->add_xframe_options(); + $this->add_http_headers(); } public function SetStyleSheet() diff --git a/datamodels/2.x/itop-hub-connector/hubconnectorpage.class.inc.php b/datamodels/2.x/itop-hub-connector/hubconnectorpage.class.inc.php index 8e8a5100d..1ce54772d 100644 --- a/datamodels/2.x/itop-hub-connector/hubconnectorpage.class.inc.php +++ b/datamodels/2.x/itop-hub-connector/hubconnectorpage.class.inc.php @@ -8,7 +8,7 @@ class HubConnectorPage extends NiceWebPage parent::__construct($sTitle); $this->no_cache(); - $this->add_xframe_options(); + $this->add_http_headers(); $sImagesDir = utils::GetAbsoluteUrlAppRoot().'images'; $sModuleImagesDir = utils::GetAbsoluteUrlModulesRoot().'itop-hub-connector/images'; diff --git a/pages/ajax.document.php b/pages/ajax.document.php index 2f0a3a5b0..1a52ee84c 100644 --- a/pages/ajax.document.php +++ b/pages/ajax.document.php @@ -62,7 +62,7 @@ try $oPage->set_cache($iCacheSec); // X-Frame http header : set in page constructor, but we need to allow frame integration for this specific page // so we're resetting its value ! (see N°3416) - $oPage->add_xframe_options(''); + $oPage->add_http_headers(''); } } break; @@ -81,7 +81,7 @@ try // X-Frame http header : set in page constructor, but we need to allow frame integration for this specific page // so we're resetting its value ! (see N°3416) - $oPage->add_xframe_options(''); + $oPage->add_http_headers(''); $oPage->add_header("Last-Modified: Wed, 15 Jun 2016 13:21:15 GMT"); // An arbitrary date in the past is ok } @@ -94,7 +94,7 @@ try // X-Frame http header : set in page constructor, but we need to allow frame integration for this specific page // so we're resetting its value ! (see N°3416) - $oPage->add_xframe_options(''); + $oPage->add_http_headers(''); $oPage->add(file_get_contents(Utils::GetCachePath().$sSignature.'.js')); break; diff --git a/setup/email.test.php b/setup/email.test.php index 3a339ac9a..738532619 100644 --- a/setup/email.test.php +++ b/setup/email.test.php @@ -38,7 +38,7 @@ $oP = new SetupPage('iTop email test utility'); // Although this page doesn't expose sensitive info, with it we can send multiple emails // So we're adding this http header to reduce CSRF exposure... -$oP->add_xframe_options('DENY'); +$oP->add_http_headers('DENY'); /** diff --git a/sources/Application/TwigBase/Controller/Controller.php b/sources/Application/TwigBase/Controller/Controller.php index 954c31938..326048812 100644 --- a/sources/Application/TwigBase/Controller/Controller.php +++ b/sources/Application/TwigBase/Controller/Controller.php @@ -687,7 +687,7 @@ abstract class Controller extends AbstractController { case self::ENUM_PAGE_TYPE_HTML: $this->m_oPage = new iTopWebPage($this->GetOperationTitle(), false); - $this->m_oPage->add_xframe_options(); + $this->m_oPage->add_http_headers(); if ($this->m_bIsBreadCrumbEnabled) { if (count($this->m_aBreadCrumbEntry) > 0) { diff --git a/sources/Application/WebPage/AjaxPage.php b/sources/Application/WebPage/AjaxPage.php index 8ef4bb340..cbea48d0f 100644 --- a/sources/Application/WebPage/AjaxPage.php +++ b/sources/Application/WebPage/AjaxPage.php @@ -46,7 +46,7 @@ class AjaxPage extends WebPage implements iTabbedPage parent::__construct($s_title, $bPrintable); //$this->add_header("Content-type: text/html; charset=utf-8"); $this->no_cache(); - $this->add_xframe_options(); + $this->add_http_headers(); $this->m_oTabs = new TabManager(); $this->sContentType = 'text/html'; $this->sContentDisposition = 'inline'; diff --git a/sources/Application/WebPage/CSVPage.php b/sources/Application/WebPage/CSVPage.php index 3aeb9aa67..00f36cd93 100644 --- a/sources/Application/WebPage/CSVPage.php +++ b/sources/Application/WebPage/CSVPage.php @@ -34,7 +34,7 @@ class CSVPage extends WebPage parent::__construct($s_title); $this->add_header("Content-type: text/plain; charset=".self::PAGES_CHARSET); $this->no_cache(); - $this->add_xframe_options(); + $this->add_http_headers(); //$this->add_header("Content-Transfer-Encoding: binary"); $oKpi->ComputeStats(get_class($this).' creation', 'CSVPage'); } diff --git a/sources/Application/WebPage/WebPage.php b/sources/Application/WebPage/WebPage.php index 21922b54a..0eef22445 100644 --- a/sources/Application/WebPage/WebPage.php +++ b/sources/Application/WebPage/WebPage.php @@ -1002,12 +1002,25 @@ JS; $this->a_headers[] = $s_header; } + /** + * @param string|null $sXFrameOptionsHeaderValue passed to {@see add_xframe_options} + * + * @return void + * @since 2.7.10 3.0.4 3.1.2 3.2.0 N°4368 method creation, replace {@see add_xframe_options} consumers call + */ + public function add_http_headers($sXFrameOptionsHeaderValue = null) + { + $this->add_xframe_options($sXFrameOptionsHeaderValue); + $this->add_xcontent_type_options(); + } + /** * @param string|null $sHeaderValue for example `SAMESITE`. If null will set the header using the config parameter value. * * @since 2.7.3 3.0.0 N°3416 * @uses security_header_xframe config parameter * @uses \utils::GetConfig() + * * @link https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/X-Frame-Options */ public function add_xframe_options($sHeaderValue = null) @@ -1019,6 +1032,17 @@ JS; $this->add_header('X-Frame-Options: '.$sHeaderValue); } + /** + * @return void + * @since 2.7.10 3.0.4 3.1.2 3.2.0 N°4368 method creation + * + * @link https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/X-Content-Type-Options + */ + public function add_xcontent_type_options() + { + $this->add_header('X-Content-Type-Options: nosniff'); + } + /** * Add needed headers to the page so that it will no be cached */ diff --git a/sources/Application/WebPage/XMLPage.php b/sources/Application/WebPage/XMLPage.php index 0f55df6dd..61ac553f8 100644 --- a/sources/Application/WebPage/XMLPage.php +++ b/sources/Application/WebPage/XMLPage.php @@ -44,7 +44,7 @@ class XMLPage extends WebPage $this->m_bHeaderSent = false; $this->add_header("Content-type: text/xml; charset=".self::PAGES_CHARSET); $this->no_cache(); - $this->add_xframe_options(); + $this->add_http_headers(); $this->add_header("Content-location: export.xml"); $oKpi->ComputeStats(get_class($this).' creation', 'XMLPage'); } diff --git a/sources/Application/WebPage/iTopWebPage.php b/sources/Application/WebPage/iTopWebPage.php index be681eb89..59e59d325 100644 --- a/sources/Application/WebPage/iTopWebPage.php +++ b/sources/Application/WebPage/iTopWebPage.php @@ -137,7 +137,7 @@ class iTopWebPage extends NiceWebPage implements iTabbedPage $this->SetRootUrl(utils::GetAbsoluteUrlAppRoot()); $this->add_header("Content-type: text/html; charset=".self::PAGES_CHARSET); $this->no_cache(); - $this->add_xframe_options(); + $this->add_http_headers(); $this->PrepareLayout(); if ($this->IsPrintableVersion()) { $oPrintHeader = $this->OutputPrintable(); diff --git a/tests/php-unit-tests/legacy-tests/benchmark.php b/tests/php-unit-tests/legacy-tests/benchmark.php index 3b4ba581e..c6b9f1196 100644 --- a/tests/php-unit-tests/legacy-tests/benchmark.php +++ b/tests/php-unit-tests/legacy-tests/benchmark.php @@ -781,7 +781,7 @@ try case 'create_structure': $oP->no_cache(); - $oP->add_xframe_options('DENY'); + $oP->add_http_headers('DENY'); $iPlannedContacts = Utils::ReadParam('plannedcontacts'); $iPlannedContracts = Utils::ReadParam('plannedcontracts'); diff --git a/webservices/export-v2.php b/webservices/export-v2.php index 40b9578d6..8c6a49108 100644 --- a/webservices/export-v2.php +++ b/webservices/export-v2.php @@ -38,7 +38,7 @@ function ReportErrorAndExit($sErrorMessage) else { $oP = new WebPage("iTop - Export"); - $oP->add_xframe_options(); + $oP->add_http_headers(); $oP->p('ERROR: '.utils::HtmlEntities($sErrorMessage)); $oP->output(); exit(EXIT_CODE_ERROR); @@ -57,7 +57,7 @@ function ReportErrorAndUsage($sErrorMessage) } else { $oP = new WebPage("iTop - Export"); - $oP->add_xframe_options(); + $oP->add_http_headers(); $oP->p('ERROR: '.$sErrorMessage); Usage($oP); $oP->output(); @@ -698,13 +698,13 @@ try // Note: Using NiceWebPage only for HTML export as it includes JS scripts & files, which makes no sense in other export formats. More over, it breaks Excel spreadsheet import. if ($oExporter instanceof HTMLBulkExport) { $oP = new NiceWebPage('iTop export'); - $oP->add_xframe_options(); + $oP->add_http_headers(); $oP->add_ready_script("$('table.listResults').tablesorter({widgets: ['MyZebra']});"); $oP->add_linked_stylesheet(utils::GetAbsoluteUrlAppRoot().'css/font-awesome/css/all.min.css'); $oP->add_linked_stylesheet(utils::GetAbsoluteUrlAppRoot().'css/font-awesome/css/v4-shims.min.css'); } else { $oP = new WebPage('iTop export'); - $oP->add_xframe_options(); + $oP->add_http_headers(); $oP->add_style("table br { mso-data-placement:same-cell; }"); // Trick for Excel: keep line breaks inside the same cell ! } $oP->add_style("body { overflow: auto; }"); @@ -724,7 +724,7 @@ catch (BulkExportMissingParameterException $e) { } catch (Exception $e) { $oP = new WebPage('iTop Export'); - $oP->add_xframe_options(); + $oP->add_http_headers(); $oP->add('Error: '.utils::HtmlEntities($e->getMessage())); IssueLog::Error(utils::HtmlEntities($e->getMessage())."\n".$e->getTraceAsString()); $oP->output();