mirror of
https://github.com/the-djmaze/snappymail.git
synced 2024-12-24 08:04:16 +08:00
Make <script> secure with CSP, see issue #103
This commit is contained in:
parent
66560be455
commit
a3d2b560d0
3 changed files with 29 additions and 8 deletions
|
@ -1,3 +1,4 @@
|
|||
[].flat||document.location.replace('./?/BadBrowser');
|
||||
|
||||
(win => {
|
||||
|
||||
|
|
|
@ -62,12 +62,7 @@ class Service
|
|||
// 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 @@ class Service
|
|||
$this->oActions->Cacher()->Set($sCacheFileName, $sResult);
|
||||
}
|
||||
}
|
||||
|
||||
$sScriptNonce = \SnappyMail\UUID::generate();
|
||||
$this->setCSP($sScriptNonce);
|
||||
$sResult = \str_replace('nonce=""', 'nonce="'.$sScriptNonce.'"', $sResult);
|
||||
/*
|
||||
\preg_match('<script[^>]+>(.+)</script>', $sResult, $script);
|
||||
$sScriptHash = 'sha256-'.\base64_encode(\hash('sha256', $script[1], true));
|
||||
$this->setCSP(null, $sScriptHash);
|
||||
*/
|
||||
}
|
||||
else if (!\headers_sent())
|
||||
{
|
||||
|
@ -191,6 +195,23 @@ class Service
|
|||
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);
|
||||
|
|
|
@ -15,7 +15,6 @@
|
|||
<link type="text/css" rel="stylesheet" data-href="{{BaseAppMainCssLink}}" id="rl-css" rel="preload">
|
||||
<link rel="manifest" href="{{BaseAppManifestLink}}">
|
||||
<style id="app-theme-style" data-href="{{BaseAppThemeCssLink}}">{{BaseAppThemeCss}}</style>
|
||||
<script>[].flat||document.location.replace('./?/BadBrowser');</script>
|
||||
{{BaseAppFaviconPngLinkTag}}
|
||||
{{BaseAppFaviconTouchLinkTag}}
|
||||
</head>
|
||||
|
@ -38,7 +37,7 @@
|
|||
</div>
|
||||
</div>
|
||||
{{BaseTemplates}}
|
||||
<script type="text/javascript">{{BaseAppBootScript}}{{BaseLanguage}}</script>
|
||||
<script nonce="" type="text/javascript">{{BaseAppBootScript}}{{BaseLanguage}}</script>
|
||||
</body>
|
||||
|
||||
</html>
|
||||
|
|
Loading…
Reference in a new issue