Skip to content

Commit

Permalink
Make <script> secure with CSP, see issue #103
Browse files Browse the repository at this point in the history
  • Loading branch information
djmaze committed Jul 28, 2021
1 parent 66560be commit a3d2b56
Show file tree
Hide file tree
Showing 3 changed files with 29 additions and 8 deletions.
1 change: 1 addition & 0 deletions dev/boot.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
[].flat||document.location.replace('./?/BadBrowser');

(win => {

Expand Down
33 changes: 27 additions & 6 deletions snappymail/v/0.0.0/app/libraries/RainLoop/Service.php
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down Expand Up @@ -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('<script[^>]+>(.+)</script>', $sResult, $script);
$sScriptHash = 'sha256-'.\base64_encode(\hash('sha256', $script[1], true));
$this->setCSP(null, $sScriptHash);
*/
}
else if (!\headers_sent())
{
Expand All @@ -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);
Expand Down
3 changes: 1 addition & 2 deletions snappymail/v/0.0.0/app/templates/Index.html
Original file line number Diff line number Diff line change
Expand Up @@ -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>
Expand All @@ -38,7 +37,7 @@
</div>
</div>
{{BaseTemplates}}
<script type="text/javascript">{{BaseAppBootScript}}{{BaseLanguage}}</script>
<script nonce="" type="text/javascript">{{BaseAppBootScript}}{{BaseLanguage}}</script>
</body>

</html>

0 comments on commit a3d2b56

Please sign in to comment.