diff --git a/dev/boot.js b/dev/boot.js index 0d8ffb98d4..1db5a90261 100644 --- a/dev/boot.js +++ b/dev/boot.js @@ -1,3 +1,4 @@ +[].flat||document.location.replace('./?/BadBrowser'); (win => { diff --git a/snappymail/v/0.0.0/app/libraries/RainLoop/Service.php b/snappymail/v/0.0.0/app/libraries/RainLoop/Service.php index e051540fab..7c13386f9a 100644 --- a/snappymail/v/0.0.0/app/libraries/RainLoop/Service.php +++ b/snappymail/v/0.0.0/app/libraries/RainLoop/Service.php @@ -62,12 +62,7 @@ public function RunResult() : bool // Google FLoC \header('Permissions-Policy: interest-cohort=()'); - $sContentSecurityPolicy = \trim($this->oActions->Config()->Get('security', 'content_security_policy', '')) ?: APP_DEFAULT_CSP; - if ($this->oActions->Config()->Get('security', 'use_local_proxy_for_external_images', '')) { - $sContentSecurityPolicy = preg_replace('/(img-src[^;]+)\\shttps:(\\s|;|$)/D', '$1$2', $sContentSecurityPolicy); - $sContentSecurityPolicy = preg_replace('/(img-src[^;]+)\\shttp:(\\s|;|$)/D', '$1$2', $sContentSecurityPolicy); - } - \header('Content-Security-Policy: '.$sContentSecurityPolicy, true); + $this->setCSP(); $sXFrameOptionsHeader = \trim($this->oActions->Config()->Get('security', 'x_frame_options_header', '')) ?: 'DENY'; \header('X-Frame-Options: '.$sXFrameOptionsHeader, true); @@ -176,6 +171,15 @@ public function RunResult() : bool $this->oActions->Cacher()->Set($sCacheFileName, $sResult); } } + + $sScriptNonce = \SnappyMail\UUID::generate(); + $this->setCSP($sScriptNonce); + $sResult = \str_replace('nonce=""', 'nonce="'.$sScriptNonce.'"', $sResult); +/* + \preg_match(']+>(.+)', $sResult, $script); + $sScriptHash = 'sha256-'.\base64_encode(\hash('sha256', $script[1], true)); + $this->setCSP(null, $sScriptHash); +*/ } else if (!\headers_sent()) { @@ -191,6 +195,23 @@ public function RunResult() : bool return true; } + private function setCSP(string $sScriptNonce = null) : void + { + $sContentSecurityPolicy = \trim($this->oActions->Config()->Get('security', 'content_security_policy', '')) ?: APP_DEFAULT_CSP; + if ($this->oActions->Config()->Get('security', 'use_local_proxy_for_external_images', '')) { + $sContentSecurityPolicy = \preg_replace('/(img-src[^;]+)\\shttps:(\\s|;|$)/D', '$1$2', $sContentSecurityPolicy); + $sContentSecurityPolicy = \preg_replace('/(img-src[^;]+)\\shttp:(\\s|;|$)/D', '$1$2', $sContentSecurityPolicy); + } + // Internet Explorer does not support 'nonce' + if (!\strpos($_SERVER['HTTP_USER_AGENT'], 'Trident/')) { + if ($sScriptNonce) { + $sContentSecurityPolicy = \preg_replace("/(script-src[^;]+)'unsafe-inline'/", "\$1'nonce-{$sScriptNonce}'", $sContentSecurityPolicy); + } + $sContentSecurityPolicy = \preg_replace("/(script-src[^;]+)'unsafe-inline'/", '', $sContentSecurityPolicy); + } + \header('Content-Security-Policy: '.$sContentSecurityPolicy, true); + } + private function staticPath(string $sPath) : string { return $this->oActions->StaticPath($sPath); diff --git a/snappymail/v/0.0.0/app/templates/Index.html b/snappymail/v/0.0.0/app/templates/Index.html index 171350f16f..8dd65439d0 100644 --- a/snappymail/v/0.0.0/app/templates/Index.html +++ b/snappymail/v/0.0.0/app/templates/Index.html @@ -15,7 +15,6 @@ - {{BaseAppFaviconPngLinkTag}} {{BaseAppFaviconTouchLinkTag}} @@ -38,7 +37,7 @@ {{BaseTemplates}} - +