N°3416 XFrame-Options header is now set using a config parameter, defaults to SAMEORIGIN

Also adds an indirection (\WebPage::add_xframe_options) to set header
This commit is contained in:
Pierre Goiffon
2020-12-02 16:47:28 +01:00
parent 1cf1473d6b
commit 8bfcb14d0c
12 changed files with 58 additions and 35 deletions

View File

@@ -44,7 +44,7 @@ class ajax_page extends WebPage implements iTabbedPage
$this->add_header('Cache-control: no-cache, no-store, must-revalidate');
$this->add_header('Pragma: no-cache');
$this->add_header('Expires: 0');
$this->add_header('X-Frame-Options: deny');
$this->add_xframe_options();
$this->m_oTabs = new TabManager();
$this->sContentType = 'text/html';
$this->sContentDisposition = 'inline';

View File

@@ -35,7 +35,7 @@ class CSVPage extends WebPage
$this->add_header('Cache-control: no-cache, no-store, must-revalidate');
$this->add_header('Pragma: no-cache');
$this->add_header('Expires: 0');
$this->add_header('X-Frame-Options: deny');
$this->add_xframe_options();
//$this->add_header("Content-Transfer-Encoding: binary");
}

View File

@@ -74,7 +74,7 @@ class iTopWebPage extends NiceWebPage implements iTabbedPage
$this->add_header('Cache-control: no-cache, no-store, must-revalidate');
$this->add_header('Pragma: no-cache');
$this->add_header('Expires: 0');
$this->add_header('X-Frame-Options: deny');
$this->add_xframe_options();
$this->add_linked_stylesheet("../css/jquery.treeview.css");
$this->add_linked_stylesheet("../css/jquery.autocomplete.css");
$this->add_linked_stylesheet("../css/jquery-ui-timepicker-addon.css");

View File

@@ -87,7 +87,7 @@ class LoginWebPage extends NiceWebPage
$this->add_header('Cache-control: no-cache, no-store, must-revalidate');
$this->add_header('Pragma: no-cache');
$this->add_header('Expires: 0');
$this->add_header('X-Frame-Options: deny');
$this->add_xframe_options();
}
public function SetStyleSheet()

View File

@@ -482,6 +482,23 @@ class WebPage implements Page
$this->a_headers[] = $s_header;
}
/**
* @param string|null $sHeaderValue for example `SAMESITE`. If null will set the header using the config parameter value.
*
* @since 2.7.2-2 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)
{
if (is_null($sHeaderValue)) {
$sHeaderValue = utils::GetConfig()->Get('security_header_xframe');
}
$this->add_header('X-Frame-Options: '.$sHeaderValue);
}
/**
* Add needed headers to the page so that it will no be cached
*/
@@ -490,7 +507,7 @@ class WebPage implements Page
$this->add_header('Cache-control: no-cache, no-store, must-revalidate');
$this->add_header('Pragma: no-cache');
$this->add_header('Expires: 0');
$this->add_header('X-Frame-Options: deny');
$this->add_xframe_options(); //FIXME shouldn't be done here !!!!!
}
/**

View File

@@ -46,7 +46,7 @@ class XMLPage extends WebPage
$this->add_header('Cache-control: no-cache, no-store, must-revalidate');
$this->add_header('Pragma: no-cache');
$this->add_header('Expires: 0');
$this->add_header('X-Frame-Options: deny');
$this->add_xframe_options();
$this->add_header("Content-location: export.xml");
}

View File

@@ -1249,6 +1249,14 @@ class Config
'source_of_value' => '',
'show_in_conf_sample' => false,
),
'security_header_xframe' => [
'type' => 'string',
'description' => 'Value of the X-Frame-Options HTTP header sent by iTop. Possible values : DENY, SAMEORIGIN, or empty string.',
'default' => 'SAMEORIGIN',
'value' => '',
'source_of_value' => '',
'show_in_conf_sample' => false,
],
);

View File

@@ -4,20 +4,20 @@ class HubConnectorPage extends NiceWebPage
{
public function __construct($sTitle)
{
parent::__construct($sTitle);
parent::__construct($sTitle);
$this->add_header('Cache-control: no-cache, no-store, must-revalidate');
$this->add_header('Pragma: no-cache');
$this->add_header('Expires: 0');
$this->add_header('X-Frame-Options: deny');
$this->add_xframe_options();
$sImagesDir = utils::GetAbsoluteUrlAppRoot().'images';
$sModuleImagesDir = utils::GetAbsoluteUrlModulesRoot().'itop-hub-connector/images';
$sUserPrefs = appUserPreferences::GetAsJSON();
$this->add_linked_script(utils::GetAbsoluteUrlAppRoot().'js/utils.js');
$this->add_script(
<<<EOF
$sImagesDir = utils::GetAbsoluteUrlAppRoot().'images';
$sModuleImagesDir = utils::GetAbsoluteUrlModulesRoot().'itop-hub-connector/images';
$sUserPrefs = appUserPreferences::GetAsJSON();
$this->add_linked_script(utils::GetAbsoluteUrlAppRoot().'js/utils.js');
$this->add_script(
<<<EOF
var oUserPreferences = $sUserPrefs;
EOF
);

View File

@@ -62,9 +62,10 @@ try
ormDocument::DownloadDocument($oPage, $sClass, $id, $sField, 'attachment');
if ($iCacheSec > 0)
{
$oPage->add_header("Expires: "); // Reset the value set in ajax_page
$oPage->add_header("Cache-Control: no-transform,public,max-age=$iCacheSec,s-maxage=$iCacheSec");
$oPage->add_header("Pragma: cache"); // Reset the value set .... where ?
$oPage->add_header("Expires: "); // Reset the value set in ajax_page
$oPage->add_xframe_options('');
$oPage->add_header("Last-Modified: Wed, 15 Jun 2015 13:21:15 GMT"); // An arbitrary date in the past is ok
}
}
@@ -76,12 +77,12 @@ try
$id = utils::ReadParam('id', '');
$sSecret = utils::ReadParam('s', '');
$iCacheSec = 31556926; // One year ahead: an inline image cannot change
if (!empty($id) && !empty($sSecret))
{
if (!empty($id) && !empty($sSecret)) {
ormDocument::DownloadDocument($oPage, 'InlineImage', $id, 'contents', 'inline', 'secret', $sSecret);
$oPage->add_header("Expires: "); // Reset the value set in ajax_page
$oPage->add_header("Cache-Control: no-transform,public,max-age=$iCacheSec,s-maxage=$iCacheSec");
$oPage->add_header("Pragma: cache"); // Reset the value set .... where ?
$oPage->add_header("Expires: "); // Reset the value set in ajax_page
$oPage->add_xframe_options('');
$oPage->add_header("Last-Modified: Wed, 15 Jun 2016 13:21:15 GMT"); // An arbitrary date in the past is ok
}
break;
@@ -92,6 +93,7 @@ try
$oPage->SetContentType('text/javascript');
$oPage->add_header('Cache-control: public, max-age=86400'); // Cache for 24 hours
$oPage->add_header("Pragma: cache"); // Reset the value set .... where ?
$oPage->add_xframe_options('');
$oPage->add(file_get_contents(Utils::GetCachePath().$sSignature.'.js'));
break;

View File

@@ -961,7 +961,7 @@ try
if (!empty($sClass) && ($sClass != 'InlineImage') && !empty($id) && !empty($sField))
{
$oKPI = new ExecutionKPI();
$oPage->add_header('X-Frame-Options:'); // resets header, see N°3416
$oPage->add_xframe_options(''); // resets header, see N°3416
ormDocument::DownloadDocument($oPage, $sClass, $id, $sField, 'inline');
$oKPI->ComputeAndReport('Data fetch and format');
}

View File

@@ -558,7 +558,7 @@ abstract class Controller
{
case 'html':
$this->m_oPage = new iTopWebPage($this->GetOperationTitle());
$this->m_oPage->add_header('X-Frame-Options: deny');
$this->m_oPage->add_xframe_options();
break;
case 'ajax':

View File

@@ -44,7 +44,7 @@ function ReportErrorAndExit($sErrorMessage)
else
{
$oP = new WebPage("iTop - Export");
$oP->add_header('X-Frame-Options: deny');
$oP->add_xframe_options();
$oP->p('ERROR: '.$sErrorMessage);
$oP->output();
exit(-1);
@@ -61,10 +61,9 @@ function ReportErrorAndUsage($sErrorMessage)
$oP->output();
exit(-1);
}
else
{
else {
$oP = new WebPage("iTop - Export");
$oP->add_header('X-Frame-Options: deny');
$oP->add_xframe_options();
$oP->p('ERROR: '.$sErrorMessage);
Usage($oP);
$oP->output();
@@ -728,19 +727,17 @@ try
if ($sMimeType == 'text/html')
{
// 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)
{
if($oExporter instanceof HTMLBulkExport) {
$oP = new NiceWebPage('iTop export');
$oP->add_header('X-Frame-Options: deny');
$oP->add_xframe_options();
$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
{
else {
$oP = new WebPage('iTop export');
$oP->add_header('X-Frame-Options: deny');
$oP->add_style("table br { mso-data-placement:same-cell; }"); // Trick for Excel: keep line breaks inside the same cell !
$oP->add_xframe_options();
$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; }");
}
@@ -760,10 +757,9 @@ catch (BulkExportMissingParameterException $e)
Usage($oP);
$oP->output();
}
catch (Exception $e)
{
catch (Exception $e) {
$oP = new WebPage('iTop Export');
$oP->add_header('X-Frame-Options: deny');
$oP->add_xframe_options();
$oP->add('Error: '.$e->getMessage());
IssueLog::Error($e->getMessage()."\n".$e->getTraceAsString());
$oP->output();