mirror of
https://github.com/the-djmaze/snappymail.git
synced 2026-07-10 15:08:28 +03:00
Improved handling of Content-Security-Policy
This commit is contained in:
parent
5cd5f77c6f
commit
92d967f1e6
5 changed files with 77 additions and 32 deletions
|
|
@ -0,0 +1,50 @@
|
|||
<?php
|
||||
|
||||
namespace OCA\SnappyMail;
|
||||
|
||||
class ContentSecurityPolicy extends \OCP\AppFramework\Http\ContentSecurityPolicy {
|
||||
|
||||
/** @var bool Whether inline JS snippets are allowed */
|
||||
protected $inlineScriptAllowed = false;
|
||||
/** @var bool Whether eval in JS scripts is allowed */
|
||||
protected $evalScriptAllowed = true;
|
||||
/** @var bool Whether strict-dynamic should be set */
|
||||
protected $strictDynamicAllowed = true; // NC24+
|
||||
/** @var bool Whether inline CSS is allowed */
|
||||
protected $inlineStyleAllowed = true;
|
||||
|
||||
function __construct() {
|
||||
$CSP = \RainLoop\Api::getCSP();
|
||||
|
||||
$this->allowedScriptDomains = \array_unique(\array_merge(
|
||||
$this->allowedScriptDomains,
|
||||
$CSP->script
|
||||
));
|
||||
$this->allowedScriptDomains = \array_diff($this->allowedScriptDomains, ["'unsafe-inline'", "'unsafe-eval'"]);
|
||||
if (\method_exists($this, 'useStrictDynamic')) {
|
||||
$this->allowedScriptDomains = \array_diff($this->allowedScriptDomains, ["'strict-dynamic'"]);
|
||||
}
|
||||
|
||||
$this->allowedImageDomains = \array_unique(\array_merge(
|
||||
$this->allowedImageDomains,
|
||||
$CSP->img
|
||||
));
|
||||
|
||||
$this->allowedStyleDomains = \array_unique(\array_merge(
|
||||
$this->allowedStyleDomains,
|
||||
$CSP->style
|
||||
));
|
||||
$this->allowedStyleDomains = \array_diff($this->allowedStyleDomains, ["'unsafe-inline'"]);
|
||||
|
||||
$this->allowedFrameDomains = \array_unique(\array_merge(
|
||||
$this->allowedFrameDomains,
|
||||
$CSP->frame
|
||||
));
|
||||
|
||||
$this->reportTo = \array_unique(\array_merge(
|
||||
$this->reportTo,
|
||||
$CSP->report_to
|
||||
));
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -3,9 +3,9 @@
|
|||
namespace OCA\SnappyMail\Controller;
|
||||
|
||||
use OCA\SnappyMail\Util\SnappyMailHelper;
|
||||
use OCA\SnappyMail\ContentSecurityPolicy;
|
||||
|
||||
use OCP\AppFramework\Controller;
|
||||
use OCP\AppFramework\Http\ContentSecurityPolicy;
|
||||
use OCP\AppFramework\Http\TemplateResponse;
|
||||
|
||||
class PageController extends Controller
|
||||
|
|
@ -80,19 +80,7 @@ class PageController extends Controller
|
|||
|
||||
$response = new TemplateResponse('snappymail', 'index_embed', $params);
|
||||
|
||||
$csp = new ContentSecurityPolicy();
|
||||
// $csp->addAllowedScriptDomain("'self'");
|
||||
// CSP level 3
|
||||
\method_exists($csp, 'useStrictDynamic')
|
||||
? $csp->useStrictDynamic(true) // NC24+
|
||||
: $csp->addAllowedScriptDomain("'strict-dynamic'");
|
||||
// Else CSP level 2
|
||||
$csp->addAllowedScriptDomain("'unsafe-inline'"); // ignored by CSP 3 'strict-dynamic'
|
||||
$csp->allowEvalScript(true); // $csp->addAllowedScriptDomain("'unsafe-eval'");
|
||||
// $csp->addAllowedStyleDomain("'self'");
|
||||
// $csp->addAllowedStyleDomain("'unsafe-inline'");
|
||||
// $csp->addAllowedImageDomain("data:");
|
||||
$response->setContentSecurityPolicy($csp);
|
||||
$response->setContentSecurityPolicy(new ContentSecurityPolicy());
|
||||
|
||||
return $response;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -46,6 +46,28 @@ abstract class Api
|
|||
return $oConfig;
|
||||
}
|
||||
|
||||
public static function getCSP(string $sScriptNonce = null) : \SnappyMail\HTTP\CSP
|
||||
{
|
||||
$oConfig = static::Config();
|
||||
$CSP = new \SnappyMail\HTTP\CSP(\trim($oConfig->Get('security', 'content_security_policy', '')));
|
||||
$CSP->report = $oConfig->Get('security', 'csp_report', false);
|
||||
$CSP->report_only = $oConfig->Get('debug', 'enable', false); // '0.0.0' === APP_VERSION
|
||||
// $CSP->frame = \explode(' ', $oConfig->Get('security', 'csp_frame', ''));
|
||||
|
||||
// Allow https: due to remote images in e-mails or use proxy
|
||||
if (!$oConfig->Get('security', 'use_local_proxy_for_external_images', '')) {
|
||||
$CSP->img[] = 'https:';
|
||||
$CSP->img[] = 'http:';
|
||||
}
|
||||
if ($sScriptNonce) {
|
||||
$CSP->script[] = "'nonce-{$sScriptNonce}'";
|
||||
}
|
||||
|
||||
static::Actions()->Plugins()->RunHook('main.content-security-policy', array($CSP));
|
||||
|
||||
return $CSP;
|
||||
}
|
||||
|
||||
public static function Logger() : \MailSo\Log\Logger
|
||||
{
|
||||
static $oLogger = null;
|
||||
|
|
|
|||
|
|
@ -232,22 +232,6 @@ abstract class Service
|
|||
|
||||
private static function setCSP(string $sScriptNonce = null) : void
|
||||
{
|
||||
$CSP = new \SnappyMail\HTTP\CSP(\trim(Api::Config()->Get('security', 'content_security_policy', '')));
|
||||
$CSP->report = Api::Config()->Get('security', 'csp_report', false);
|
||||
$CSP->report_only = Api::Config()->Get('debug', 'enable', false); // '0.0.0' === APP_VERSION
|
||||
// $CSP->frame = \explode(' ', Api::Config()->Get('security', 'csp_frame', ''));
|
||||
|
||||
// Allow https: due to remote images in e-mails or use proxy
|
||||
if (!Api::Config()->Get('security', 'use_local_proxy_for_external_images', '')) {
|
||||
$CSP->img[] = 'https:';
|
||||
$CSP->img[] = 'http:';
|
||||
}
|
||||
if ($sScriptNonce) {
|
||||
$CSP->script[] = "'nonce-{$sScriptNonce}'";
|
||||
}
|
||||
|
||||
Api::Actions()->Plugins()->RunHook('main.content-security-policy', array($CSP));
|
||||
|
||||
$CSP->setHeaders();
|
||||
Api::getCSP($sScriptNonce)->setHeaders();
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -12,7 +12,8 @@ class CSP
|
|||
$default = ["'self'"],
|
||||
// Knockout.js requires unsafe-inline?
|
||||
// Knockout.js requires eval() for observable binding purposes
|
||||
$script = ["'self'", "'unsafe-eval'"/*, "'unsafe-inline'"*/],
|
||||
$script = ["'strict-dynamic'", "'unsafe-eval'"],
|
||||
// $script = ["'self'", "'unsafe-inline'", "'unsafe-eval'"],
|
||||
$img = ["'self'", 'data:'],
|
||||
$style = ["'self'", "'unsafe-inline'"],
|
||||
$frame = [],
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue