From 9ea0159d04fcc36ab9ca00cfd8d11a000be7482c Mon Sep 17 00:00:00 2001 From: Ferdinand Thiessen Date: Fri, 17 Nov 2023 10:56:02 +0100 Subject: [PATCH] feat(ContentSecurityPolicy): Allow to set `strict-dynamic` on `script-src-elem` only This adds the possibility to set `strict-dynamic` on `script-src-elem` only while keep the default rules for `script-src`. The idea is to allow loading module js which imports other files and thus does not allow nonces on import but on the initial script tag. Signed-off-by: Ferdinand Thiessen --- .../Security/CSP/ContentSecurityPolicy.php | 8 ++++ .../Http/ContentSecurityPolicy.php | 2 + .../Http/EmptyContentSecurityPolicy.php | 34 ++++++++++++++--- .../Http/ContentSecurityPolicyTest.php | 37 +++++++++++++++++++ .../Http/EmptyContentSecurityPolicyTest.php | 36 ++++++++++++++++++ 5 files changed, 111 insertions(+), 6 deletions(-) diff --git a/lib/private/Security/CSP/ContentSecurityPolicy.php b/lib/private/Security/CSP/ContentSecurityPolicy.php index eca3e2b6b2940..ee525af4c2a51 100644 --- a/lib/private/Security/CSP/ContentSecurityPolicy.php +++ b/lib/private/Security/CSP/ContentSecurityPolicy.php @@ -191,4 +191,12 @@ public function isStrictDynamicAllowed(): bool { public function setStrictDynamicAllowed(bool $strictDynamicAllowed): void { $this->strictDynamicAllowed = $strictDynamicAllowed; } + + public function isStrictDynamicAllowedOnScripts(): bool { + return $this->strictDynamicAllowedOnScripts; + } + + public function setStrictDynamicAllowedOnScripts(bool $strictDynamicAllowedOnScripts): void { + $this->strictDynamicAllowedOnScripts = $strictDynamicAllowedOnScripts; + } } diff --git a/lib/public/AppFramework/Http/ContentSecurityPolicy.php b/lib/public/AppFramework/Http/ContentSecurityPolicy.php index f17dd9bd27048..386d908ffb66d 100644 --- a/lib/public/AppFramework/Http/ContentSecurityPolicy.php +++ b/lib/public/AppFramework/Http/ContentSecurityPolicy.php @@ -48,6 +48,8 @@ class ContentSecurityPolicy extends EmptyContentSecurityPolicy { protected ?bool $evalWasmAllowed = false; /** @var bool Whether strict-dynamic should be set */ protected $strictDynamicAllowed = false; + /** @var bool Whether strict-dynamic should be set for 'script-src-elem' */ + protected $strictDynamicAllowedOnScripts = false; /** @var array Domains from which scripts can get loaded */ protected $allowedScriptDomains = [ '\'self\'', diff --git a/lib/public/AppFramework/Http/EmptyContentSecurityPolicy.php b/lib/public/AppFramework/Http/EmptyContentSecurityPolicy.php index 7e1de2ef2eb93..960efa75d2c65 100644 --- a/lib/public/AppFramework/Http/EmptyContentSecurityPolicy.php +++ b/lib/public/AppFramework/Http/EmptyContentSecurityPolicy.php @@ -41,6 +41,8 @@ class EmptyContentSecurityPolicy { protected $useJsNonce = null; /** @var bool Whether strict-dynamic should be used */ protected $strictDynamicAllowed = null; + /** @var bool Whether strict-dynamic should be used on script-src-elem */ + protected $strictDynamicAllowedOnScripts = null; /** * @var bool Whether eval in JS scripts is allowed * TODO: Disallow per default @@ -93,6 +95,18 @@ public function useStrictDynamic(bool $state = false): self { return $this; } + /** + * In contrast to `useStrictDynamic` this only sets strict-dynamic on script-src-elem + * Meaning only grants trust to all imports of scripts that were loaded in `