diff --git a/application/ajaxwebpage.class.inc.php b/application/ajaxwebpage.class.inc.php index ae4dd44d4..1f81735d9 100644 --- a/application/ajaxwebpage.class.inc.php +++ b/application/ajaxwebpage.class.inc.php @@ -51,6 +51,16 @@ class ajax_page extends WebPage implements iTabbedPage utils::InitArchiveMode(); } + /** + * Disabling sending the header so that resource won't be blocked by CORB. See parent method documentation. + * @return void + * @since 2.7.10 3.0.4 3.1.2 3.2.0 N°4368 method creation + */ + public function add_xcontent_type_options() + { + // Nothing to do ! + } + /** * @inheritDoc * @throws \Exception diff --git a/application/webpage.class.inc.php b/application/webpage.class.inc.php index 4af74c889..c54877097 100644 --- a/application/webpage.class.inc.php +++ b/application/webpage.class.inc.php @@ -495,13 +495,12 @@ class WebPage implements Page } /** - * @param string|null $sHeaderValue for example `SAMESITE`. If null will set the header using the config parameter value. + * @param string|null $sHeaderValue for example `SAMESITE`. If null will set the header using the `security_header_xframe` 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 + * @link https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/X-Frame-Options HTTP header MDN documentation */ public function add_xframe_options($sHeaderValue = null) { @@ -513,13 +512,34 @@ class WebPage implements Page } /** + * Warning : this header will trigger the Cross-Origin Read Blocking (CORB) protection for some mime types (HTML, XML except SVG, JSON, text/plain) + * In consequence some children pages will override this method. + * + * Sending header can be disabled globally using the `security.enable_header_xcontent_type_options` optional config parameter. + * * @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 + * @link https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/X-Content-Type-Options HTTP header MDN documentation + * @link https://chromium.googlesource.com/chromium/src/+/master/services/network/cross_origin_read_blocking_explainer.md#determining-whether-a-response-is-corb_protected "Determining whether a response is CORB-protected" */ public function add_xcontent_type_options() { + try { + $oConfig = utils::GetConfig(); + } catch (ConfigException|CoreException $e) { + $oConfig = null; + } + if (is_null($oConfig)) { + $bSendXContentTypeOptionsHttpHeader = true; + } else { + $bSendXContentTypeOptionsHttpHeader = $oConfig->Get('security.enable_header_xcontent_type_options'); + } + + if ($bSendXContentTypeOptionsHttpHeader === false) { + return; + } + $this->add_header('X-Content-Type-Options: nosniff'); } diff --git a/application/xmlpage.class.inc.php b/application/xmlpage.class.inc.php index fee79a4ea..017fc7fe5 100644 --- a/application/xmlpage.class.inc.php +++ b/application/xmlpage.class.inc.php @@ -48,6 +48,16 @@ class XMLPage extends WebPage $this->add_header("Content-location: export.xml"); } + /** + * Disabling sending the header so that resource won't be blocked by CORB. See parent method documentation. + * @return void + * @since 2.7.10 3.0.4 3.1.2 3.2.0 N°4368 method creation + */ + public function add_xcontent_type_options() + { + // Nothing to do ! + } + public function output() { if (!$this->m_bPassThrough) diff --git a/core/config.class.inc.php b/core/config.class.inc.php index d78d3bb48..e9d61596d 100644 --- a/core/config.class.inc.php +++ b/core/config.class.inc.php @@ -1320,6 +1320,14 @@ class Config 'source_of_value' => '', 'show_in_conf_sample' => false, ], + 'security.enable_header_xcontent_type_options' => [ + 'type' => 'bool', + 'description' => 'If set to false, iTop will stop sending the X-Content-Type-Options HTTP header. This header could trigger CORB protection on certain resources (JSON, XML, HTML, text) therefore blocking them.', + 'default' => true, + 'value' => '', + 'source_of_value' => '', + 'show_in_conf_sample' => false, + ], 'behind_reverse_proxy' => [ 'type' => 'bool', 'description' => 'If true, then proxies custom header (X-Forwarded-*) are taken into account. Use only if the webserver is not publicly accessible (reachable only by the reverse proxy)',