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}}
-
+