diff options
author | Ferdinand Thiessen <opensource@fthiessen.de> | 2023-11-17 18:03:54 +0100 |
---|---|---|
committer | GitHub <noreply@github.com> | 2023-11-17 18:03:54 +0100 |
commit | 4fa2749fa8666e5ce1e6d5c0a98e7a29600b49c0 (patch) | |
tree | af6377150ddb12b76271c6a90dc525401109bc76 | |
parent | 8e3a08d1618f705afbcfd1c1681e39fdce91fe26 (diff) | |
parent | e231abd9bfac66e69db810c986792f9ba1a9d581 (diff) | |
download | nextcloud-server-4fa2749fa8666e5ce1e6d5c0a98e7a29600b49c0.tar.gz nextcloud-server-4fa2749fa8666e5ce1e6d5c0a98e7a29600b49c0.zip |
Merge pull request #41571 from nextcloud/fix/allow-strict-dynamic-elem
Allow setting `strict-dynamic` on `strict-src-elem` and set it by default
6 files changed, 167 insertions, 65 deletions
diff --git a/lib/private/Security/CSP/ContentSecurityPolicy.php b/lib/private/Security/CSP/ContentSecurityPolicy.php index eca3e2b6b29..ee525af4c2a 100644 --- a/lib/private/Security/CSP/ContentSecurityPolicy.php +++ b/lib/private/Security/CSP/ContentSecurityPolicy.php @@ -191,4 +191,12 @@ class ContentSecurityPolicy extends \OCP\AppFramework\Http\ContentSecurityPolicy 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 f17dd9bd270..7f93f7004d9 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 = true; /** @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 7e1de2ef2eb..960efa75d2c 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 @@ -94,6 +96,18 @@ class EmptyContentSecurityPolicy { } /** + * 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 `<script>` tags, and thus weakens less the CSP. + * @param bool $state + * @return EmptyContentSecurityPolicy + * @since 28.0.0 + */ + public function useStrictDynamicOnScripts(bool $state = false): self { + $this->strictDynamicAllowedOnScripts = $state; + return $this; + } + + /** * Use the according JS nonce * This method is only for CSPMiddleware, custom values are ignored in mergePolicies of ContentSecurityPolicyManager * @@ -448,27 +462,35 @@ class EmptyContentSecurityPolicy { if (!empty($this->allowedScriptDomains) || $this->evalScriptAllowed || $this->evalWasmAllowed) { $policy .= 'script-src '; + $scriptSrc = ''; if (is_string($this->useJsNonce)) { if ($this->strictDynamicAllowed) { - $policy .= '\'strict-dynamic\' '; + $scriptSrc .= '\'strict-dynamic\' '; } - $policy .= '\'nonce-'.base64_encode($this->useJsNonce).'\''; + $scriptSrc .= '\'nonce-'.base64_encode($this->useJsNonce).'\''; $allowedScriptDomains = array_flip($this->allowedScriptDomains); unset($allowedScriptDomains['\'self\'']); $this->allowedScriptDomains = array_flip($allowedScriptDomains); if (count($allowedScriptDomains) !== 0) { - $policy .= ' '; + $scriptSrc .= ' '; } } if (is_array($this->allowedScriptDomains)) { - $policy .= implode(' ', $this->allowedScriptDomains); + $scriptSrc .= implode(' ', $this->allowedScriptDomains); } if ($this->evalScriptAllowed) { - $policy .= ' \'unsafe-eval\''; + $scriptSrc .= ' \'unsafe-eval\''; } if ($this->evalWasmAllowed) { - $policy .= ' \'wasm-unsafe-eval\''; + $scriptSrc .= ' \'wasm-unsafe-eval\''; } + $policy .= $scriptSrc . ';'; + } + + // We only need to set this if 'strictDynamicAllowed' is not set because otherwise we can simply fall back to script-src + if ($this->strictDynamicAllowedOnScripts && !(is_string($this->useJsNonce) && $this->strictDynamicAllowed)) { + $policy .= 'script-src-elem \'strict-dynamic\' '; + $policy .= $scriptSrc ?? ''; $policy .= ';'; } diff --git a/tests/lib/AppFramework/Http/ContentSecurityPolicyTest.php b/tests/lib/AppFramework/Http/ContentSecurityPolicyTest.php index 8e6ac32b416..97412f1de23 100644 --- a/tests/lib/AppFramework/Http/ContentSecurityPolicyTest.php +++ b/tests/lib/AppFramework/Http/ContentSecurityPolicyTest.php @@ -25,19 +25,19 @@ class ContentSecurityPolicyTest extends \Test\TestCase { } public function testGetPolicyDefault() { - $defaultPolicy = "default-src 'none';base-uri 'none';manifest-src 'self';script-src 'self';style-src 'self' 'unsafe-inline';img-src 'self' data: blob:;font-src 'self' data:;connect-src 'self';media-src 'self';frame-ancestors 'self';form-action 'self'"; + $defaultPolicy = "default-src 'none';base-uri 'none';manifest-src 'self';script-src 'self';script-src-elem 'strict-dynamic' 'self';style-src 'self' 'unsafe-inline';img-src 'self' data: blob:;font-src 'self' data:;connect-src 'self';media-src 'self';frame-ancestors 'self';form-action 'self'"; $this->assertSame($defaultPolicy, $this->contentSecurityPolicy->buildPolicy()); } public function testGetPolicyScriptDomainValid() { - $expectedPolicy = "default-src 'none';base-uri 'none';manifest-src 'self';script-src 'self' www.owncloud.com;style-src 'self' 'unsafe-inline';img-src 'self' data: blob:;font-src 'self' data:;connect-src 'self';media-src 'self';frame-ancestors 'self';form-action 'self'"; + $expectedPolicy = "default-src 'none';base-uri 'none';manifest-src 'self';script-src 'self' www.owncloud.com;script-src-elem 'strict-dynamic' 'self' www.owncloud.com;style-src 'self' 'unsafe-inline';img-src 'self' data: blob:;font-src 'self' data:;connect-src 'self';media-src 'self';frame-ancestors 'self';form-action 'self'"; $this->contentSecurityPolicy->addAllowedScriptDomain('www.owncloud.com'); $this->assertSame($expectedPolicy, $this->contentSecurityPolicy->buildPolicy()); } public function testGetPolicyScriptDomainValidMultiple() { - $expectedPolicy = "default-src 'none';base-uri 'none';manifest-src 'self';script-src 'self' www.owncloud.com www.owncloud.org;style-src 'self' 'unsafe-inline';img-src 'self' data: blob:;font-src 'self' data:;connect-src 'self';media-src 'self';frame-ancestors 'self';form-action 'self'"; + $expectedPolicy = "default-src 'none';base-uri 'none';manifest-src 'self';script-src 'self' www.owncloud.com www.owncloud.org;script-src-elem 'strict-dynamic' 'self' www.owncloud.com www.owncloud.org;style-src 'self' 'unsafe-inline';img-src 'self' data: blob:;font-src 'self' data:;connect-src 'self';media-src 'self';frame-ancestors 'self';form-action 'self'"; $this->contentSecurityPolicy->addAllowedScriptDomain('www.owncloud.com'); $this->contentSecurityPolicy->addAllowedScriptDomain('www.owncloud.org'); @@ -45,7 +45,7 @@ class ContentSecurityPolicyTest extends \Test\TestCase { } public function testGetPolicyDisallowScriptDomain() { - $expectedPolicy = "default-src 'none';base-uri 'none';manifest-src 'self';script-src 'self';style-src 'self' 'unsafe-inline';img-src 'self' data: blob:;font-src 'self' data:;connect-src 'self';media-src 'self';frame-ancestors 'self';form-action 'self'"; + $expectedPolicy = "default-src 'none';base-uri 'none';manifest-src 'self';script-src 'self';script-src-elem 'strict-dynamic' 'self';style-src 'self' 'unsafe-inline';img-src 'self' data: blob:;font-src 'self' data:;connect-src 'self';media-src 'self';frame-ancestors 'self';form-action 'self'"; $this->contentSecurityPolicy->addAllowedScriptDomain('www.owncloud.com'); $this->contentSecurityPolicy->disallowScriptDomain('www.owncloud.com'); @@ -53,7 +53,7 @@ class ContentSecurityPolicyTest extends \Test\TestCase { } public function testGetPolicyDisallowScriptDomainMultiple() { - $expectedPolicy = "default-src 'none';base-uri 'none';manifest-src 'self';script-src 'self' www.owncloud.com;style-src 'self' 'unsafe-inline';img-src 'self' data: blob:;font-src 'self' data:;connect-src 'self';media-src 'self';frame-ancestors 'self';form-action 'self'"; + $expectedPolicy = "default-src 'none';base-uri 'none';manifest-src 'self';script-src 'self' www.owncloud.com;script-src-elem 'strict-dynamic' 'self' www.owncloud.com;style-src 'self' 'unsafe-inline';img-src 'self' data: blob:;font-src 'self' data:;connect-src 'self';media-src 'self';frame-ancestors 'self';form-action 'self'"; $this->contentSecurityPolicy->addAllowedScriptDomain('www.owncloud.com'); $this->contentSecurityPolicy->disallowScriptDomain('www.owncloud.org'); @@ -61,7 +61,7 @@ class ContentSecurityPolicyTest extends \Test\TestCase { } public function testGetPolicyDisallowScriptDomainMultipleStacked() { - $expectedPolicy = "default-src 'none';base-uri 'none';manifest-src 'self';script-src 'self';style-src 'self' 'unsafe-inline';img-src 'self' data: blob:;font-src 'self' data:;connect-src 'self';media-src 'self';frame-ancestors 'self';form-action 'self'"; + $expectedPolicy = "default-src 'none';base-uri 'none';manifest-src 'self';script-src 'self';script-src-elem 'strict-dynamic' 'self';style-src 'self' 'unsafe-inline';img-src 'self' data: blob:;font-src 'self' data:;connect-src 'self';media-src 'self';frame-ancestors 'self';form-action 'self'"; $this->contentSecurityPolicy->addAllowedScriptDomain('www.owncloud.com'); $this->contentSecurityPolicy->disallowScriptDomain('www.owncloud.org')->disallowScriptDomain('www.owncloud.com'); @@ -69,21 +69,21 @@ class ContentSecurityPolicyTest extends \Test\TestCase { } public function testGetPolicyScriptDisallowEval() { - $expectedPolicy = "default-src 'none';base-uri 'none';manifest-src 'self';script-src 'self';style-src 'self' 'unsafe-inline';img-src 'self' data: blob:;font-src 'self' data:;connect-src 'self';media-src 'self';frame-ancestors 'self';form-action 'self'"; + $expectedPolicy = "default-src 'none';base-uri 'none';manifest-src 'self';script-src 'self';script-src-elem 'strict-dynamic' 'self';style-src 'self' 'unsafe-inline';img-src 'self' data: blob:;font-src 'self' data:;connect-src 'self';media-src 'self';frame-ancestors 'self';form-action 'self'"; $this->contentSecurityPolicy->allowEvalScript(false); $this->assertSame($expectedPolicy, $this->contentSecurityPolicy->buildPolicy()); } public function testGetPolicyStyleDomainValid() { - $expectedPolicy = "default-src 'none';base-uri 'none';manifest-src 'self';script-src 'self';style-src 'self' www.owncloud.com 'unsafe-inline';img-src 'self' data: blob:;font-src 'self' data:;connect-src 'self';media-src 'self';frame-ancestors 'self';form-action 'self'"; + $expectedPolicy = "default-src 'none';base-uri 'none';manifest-src 'self';script-src 'self';script-src-elem 'strict-dynamic' 'self';style-src 'self' www.owncloud.com 'unsafe-inline';img-src 'self' data: blob:;font-src 'self' data:;connect-src 'self';media-src 'self';frame-ancestors 'self';form-action 'self'"; $this->contentSecurityPolicy->addAllowedStyleDomain('www.owncloud.com'); $this->assertSame($expectedPolicy, $this->contentSecurityPolicy->buildPolicy()); } public function testGetPolicyStyleDomainValidMultiple() { - $expectedPolicy = "default-src 'none';base-uri 'none';manifest-src 'self';script-src 'self';style-src 'self' www.owncloud.com www.owncloud.org 'unsafe-inline';img-src 'self' data: blob:;font-src 'self' data:;connect-src 'self';media-src 'self';frame-ancestors 'self';form-action 'self'"; + $expectedPolicy = "default-src 'none';base-uri 'none';manifest-src 'self';script-src 'self';script-src-elem 'strict-dynamic' 'self';style-src 'self' www.owncloud.com www.owncloud.org 'unsafe-inline';img-src 'self' data: blob:;font-src 'self' data:;connect-src 'self';media-src 'self';frame-ancestors 'self';form-action 'self'"; $this->contentSecurityPolicy->addAllowedStyleDomain('www.owncloud.com'); $this->contentSecurityPolicy->addAllowedStyleDomain('www.owncloud.org'); @@ -91,7 +91,7 @@ class ContentSecurityPolicyTest extends \Test\TestCase { } public function testGetPolicyDisallowStyleDomain() { - $expectedPolicy = "default-src 'none';base-uri 'none';manifest-src 'self';script-src 'self';style-src 'self' 'unsafe-inline';img-src 'self' data: blob:;font-src 'self' data:;connect-src 'self';media-src 'self';frame-ancestors 'self';form-action 'self'"; + $expectedPolicy = "default-src 'none';base-uri 'none';manifest-src 'self';script-src 'self';script-src-elem 'strict-dynamic' 'self';style-src 'self' 'unsafe-inline';img-src 'self' data: blob:;font-src 'self' data:;connect-src 'self';media-src 'self';frame-ancestors 'self';form-action 'self'"; $this->contentSecurityPolicy->addAllowedStyleDomain('www.owncloud.com'); $this->contentSecurityPolicy->disallowStyleDomain('www.owncloud.com'); @@ -99,7 +99,7 @@ class ContentSecurityPolicyTest extends \Test\TestCase { } public function testGetPolicyDisallowStyleDomainMultiple() { - $expectedPolicy = "default-src 'none';base-uri 'none';manifest-src 'self';script-src 'self';style-src 'self' www.owncloud.com 'unsafe-inline';img-src 'self' data: blob:;font-src 'self' data:;connect-src 'self';media-src 'self';frame-ancestors 'self';form-action 'self'"; + $expectedPolicy = "default-src 'none';base-uri 'none';manifest-src 'self';script-src 'self';script-src-elem 'strict-dynamic' 'self';style-src 'self' www.owncloud.com 'unsafe-inline';img-src 'self' data: blob:;font-src 'self' data:;connect-src 'self';media-src 'self';frame-ancestors 'self';form-action 'self'"; $this->contentSecurityPolicy->addAllowedStyleDomain('www.owncloud.com'); $this->contentSecurityPolicy->disallowStyleDomain('www.owncloud.org'); @@ -107,7 +107,7 @@ class ContentSecurityPolicyTest extends \Test\TestCase { } public function testGetPolicyDisallowStyleDomainMultipleStacked() { - $expectedPolicy = "default-src 'none';base-uri 'none';manifest-src 'self';script-src 'self';style-src 'self' 'unsafe-inline';img-src 'self' data: blob:;font-src 'self' data:;connect-src 'self';media-src 'self';frame-ancestors 'self';form-action 'self'"; + $expectedPolicy = "default-src 'none';base-uri 'none';manifest-src 'self';script-src 'self';script-src-elem 'strict-dynamic' 'self';style-src 'self' 'unsafe-inline';img-src 'self' data: blob:;font-src 'self' data:;connect-src 'self';media-src 'self';frame-ancestors 'self';form-action 'self'"; $this->contentSecurityPolicy->addAllowedStyleDomain('www.owncloud.com'); $this->contentSecurityPolicy->disallowStyleDomain('www.owncloud.org')->disallowStyleDomain('www.owncloud.com'); @@ -115,35 +115,35 @@ class ContentSecurityPolicyTest extends \Test\TestCase { } public function testGetPolicyStyleAllowInline() { - $expectedPolicy = "default-src 'none';base-uri 'none';manifest-src 'self';script-src 'self';style-src 'self' 'unsafe-inline';img-src 'self' data: blob:;font-src 'self' data:;connect-src 'self';media-src 'self';frame-ancestors 'self';form-action 'self'"; + $expectedPolicy = "default-src 'none';base-uri 'none';manifest-src 'self';script-src 'self';script-src-elem 'strict-dynamic' 'self';style-src 'self' 'unsafe-inline';img-src 'self' data: blob:;font-src 'self' data:;connect-src 'self';media-src 'self';frame-ancestors 'self';form-action 'self'"; $this->contentSecurityPolicy->allowInlineStyle(true); $this->assertSame($expectedPolicy, $this->contentSecurityPolicy->buildPolicy()); } public function testGetPolicyStyleAllowInlineWithDomain() { - $expectedPolicy = "default-src 'none';base-uri 'none';manifest-src 'self';script-src 'self';style-src 'self' www.owncloud.com 'unsafe-inline';img-src 'self' data: blob:;font-src 'self' data:;connect-src 'self';media-src 'self';frame-ancestors 'self';form-action 'self'"; + $expectedPolicy = "default-src 'none';base-uri 'none';manifest-src 'self';script-src 'self';script-src-elem 'strict-dynamic' 'self';style-src 'self' www.owncloud.com 'unsafe-inline';img-src 'self' data: blob:;font-src 'self' data:;connect-src 'self';media-src 'self';frame-ancestors 'self';form-action 'self'"; $this->contentSecurityPolicy->addAllowedStyleDomain('www.owncloud.com'); $this->assertSame($expectedPolicy, $this->contentSecurityPolicy->buildPolicy()); } public function testGetPolicyStyleDisallowInline() { - $expectedPolicy = "default-src 'none';base-uri 'none';manifest-src 'self';script-src 'self';style-src 'self';img-src 'self' data: blob:;font-src 'self' data:;connect-src 'self';media-src 'self';frame-ancestors 'self';form-action 'self'"; + $expectedPolicy = "default-src 'none';base-uri 'none';manifest-src 'self';script-src 'self';script-src-elem 'strict-dynamic' 'self';style-src 'self';img-src 'self' data: blob:;font-src 'self' data:;connect-src 'self';media-src 'self';frame-ancestors 'self';form-action 'self'"; $this->contentSecurityPolicy->allowInlineStyle(false); $this->assertSame($expectedPolicy, $this->contentSecurityPolicy->buildPolicy()); } public function testGetPolicyImageDomainValid() { - $expectedPolicy = "default-src 'none';base-uri 'none';manifest-src 'self';script-src 'self';style-src 'self' 'unsafe-inline';img-src 'self' data: blob: www.owncloud.com;font-src 'self' data:;connect-src 'self';media-src 'self';frame-ancestors 'self';form-action 'self'"; + $expectedPolicy = "default-src 'none';base-uri 'none';manifest-src 'self';script-src 'self';script-src-elem 'strict-dynamic' 'self';style-src 'self' 'unsafe-inline';img-src 'self' data: blob: www.owncloud.com;font-src 'self' data:;connect-src 'self';media-src 'self';frame-ancestors 'self';form-action 'self'"; $this->contentSecurityPolicy->addAllowedImageDomain('www.owncloud.com'); $this->assertSame($expectedPolicy, $this->contentSecurityPolicy->buildPolicy()); } public function testGetPolicyImageDomainValidMultiple() { - $expectedPolicy = "default-src 'none';base-uri 'none';manifest-src 'self';script-src 'self';style-src 'self' 'unsafe-inline';img-src 'self' data: blob: www.owncloud.com www.owncloud.org;font-src 'self' data:;connect-src 'self';media-src 'self';frame-ancestors 'self';form-action 'self'"; + $expectedPolicy = "default-src 'none';base-uri 'none';manifest-src 'self';script-src 'self';script-src-elem 'strict-dynamic' 'self';style-src 'self' 'unsafe-inline';img-src 'self' data: blob: www.owncloud.com www.owncloud.org;font-src 'self' data:;connect-src 'self';media-src 'self';frame-ancestors 'self';form-action 'self'"; $this->contentSecurityPolicy->addAllowedImageDomain('www.owncloud.com'); $this->contentSecurityPolicy->addAllowedImageDomain('www.owncloud.org'); @@ -151,7 +151,7 @@ class ContentSecurityPolicyTest extends \Test\TestCase { } public function testGetPolicyDisallowImageDomain() { - $expectedPolicy = "default-src 'none';base-uri 'none';manifest-src 'self';script-src 'self';style-src 'self' 'unsafe-inline';img-src 'self' data: blob:;font-src 'self' data:;connect-src 'self';media-src 'self';frame-ancestors 'self';form-action 'self'"; + $expectedPolicy = "default-src 'none';base-uri 'none';manifest-src 'self';script-src 'self';script-src-elem 'strict-dynamic' 'self';style-src 'self' 'unsafe-inline';img-src 'self' data: blob:;font-src 'self' data:;connect-src 'self';media-src 'self';frame-ancestors 'self';form-action 'self'"; $this->contentSecurityPolicy->addAllowedImageDomain('www.owncloud.com'); $this->contentSecurityPolicy->disallowImageDomain('www.owncloud.com'); @@ -159,7 +159,7 @@ class ContentSecurityPolicyTest extends \Test\TestCase { } public function testGetPolicyDisallowImageDomainMultiple() { - $expectedPolicy = "default-src 'none';base-uri 'none';manifest-src 'self';script-src 'self';style-src 'self' 'unsafe-inline';img-src 'self' data: blob: www.owncloud.com;font-src 'self' data:;connect-src 'self';media-src 'self';frame-ancestors 'self';form-action 'self'"; + $expectedPolicy = "default-src 'none';base-uri 'none';manifest-src 'self';script-src 'self';script-src-elem 'strict-dynamic' 'self';style-src 'self' 'unsafe-inline';img-src 'self' data: blob: www.owncloud.com;font-src 'self' data:;connect-src 'self';media-src 'self';frame-ancestors 'self';form-action 'self'"; $this->contentSecurityPolicy->addAllowedImageDomain('www.owncloud.com'); $this->contentSecurityPolicy->disallowImageDomain('www.owncloud.org'); @@ -167,7 +167,7 @@ class ContentSecurityPolicyTest extends \Test\TestCase { } public function testGetPolicyDisallowImageDomainMultipleStakes() { - $expectedPolicy = "default-src 'none';base-uri 'none';manifest-src 'self';script-src 'self';style-src 'self' 'unsafe-inline';img-src 'self' data: blob:;font-src 'self' data:;connect-src 'self';media-src 'self';frame-ancestors 'self';form-action 'self'"; + $expectedPolicy = "default-src 'none';base-uri 'none';manifest-src 'self';script-src 'self';script-src-elem 'strict-dynamic' 'self';style-src 'self' 'unsafe-inline';img-src 'self' data: blob:;font-src 'self' data:;connect-src 'self';media-src 'self';frame-ancestors 'self';form-action 'self'"; $this->contentSecurityPolicy->addAllowedImageDomain('www.owncloud.com'); $this->contentSecurityPolicy->disallowImageDomain('www.owncloud.org')->disallowImageDomain('www.owncloud.com'); @@ -175,14 +175,14 @@ class ContentSecurityPolicyTest extends \Test\TestCase { } public function testGetPolicyFontDomainValid() { - $expectedPolicy = "default-src 'none';base-uri 'none';manifest-src 'self';script-src 'self';style-src 'self' 'unsafe-inline';img-src 'self' data: blob:;font-src 'self' data: www.owncloud.com;connect-src 'self';media-src 'self';frame-ancestors 'self';form-action 'self'"; + $expectedPolicy = "default-src 'none';base-uri 'none';manifest-src 'self';script-src 'self';script-src-elem 'strict-dynamic' 'self';style-src 'self' 'unsafe-inline';img-src 'self' data: blob:;font-src 'self' data: www.owncloud.com;connect-src 'self';media-src 'self';frame-ancestors 'self';form-action 'self'"; $this->contentSecurityPolicy->addAllowedFontDomain('www.owncloud.com'); $this->assertSame($expectedPolicy, $this->contentSecurityPolicy->buildPolicy()); } public function testGetPolicyFontDomainValidMultiple() { - $expectedPolicy = "default-src 'none';base-uri 'none';manifest-src 'self';script-src 'self';style-src 'self' 'unsafe-inline';img-src 'self' data: blob:;font-src 'self' data: www.owncloud.com www.owncloud.org;connect-src 'self';media-src 'self';frame-ancestors 'self';form-action 'self'"; + $expectedPolicy = "default-src 'none';base-uri 'none';manifest-src 'self';script-src 'self';script-src-elem 'strict-dynamic' 'self';style-src 'self' 'unsafe-inline';img-src 'self' data: blob:;font-src 'self' data: www.owncloud.com www.owncloud.org;connect-src 'self';media-src 'self';frame-ancestors 'self';form-action 'self'"; $this->contentSecurityPolicy->addAllowedFontDomain('www.owncloud.com'); $this->contentSecurityPolicy->addAllowedFontDomain('www.owncloud.org'); @@ -190,7 +190,7 @@ class ContentSecurityPolicyTest extends \Test\TestCase { } public function testGetPolicyDisallowFontDomain() { - $expectedPolicy = "default-src 'none';base-uri 'none';manifest-src 'self';script-src 'self';style-src 'self' 'unsafe-inline';img-src 'self' data: blob:;font-src 'self' data:;connect-src 'self';media-src 'self';frame-ancestors 'self';form-action 'self'"; + $expectedPolicy = "default-src 'none';base-uri 'none';manifest-src 'self';script-src 'self';script-src-elem 'strict-dynamic' 'self';style-src 'self' 'unsafe-inline';img-src 'self' data: blob:;font-src 'self' data:;connect-src 'self';media-src 'self';frame-ancestors 'self';form-action 'self'"; $this->contentSecurityPolicy->addAllowedFontDomain('www.owncloud.com'); $this->contentSecurityPolicy->disallowFontDomain('www.owncloud.com'); @@ -198,7 +198,7 @@ class ContentSecurityPolicyTest extends \Test\TestCase { } public function testGetPolicyDisallowFontDomainMultiple() { - $expectedPolicy = "default-src 'none';base-uri 'none';manifest-src 'self';script-src 'self';style-src 'self' 'unsafe-inline';img-src 'self' data: blob:;font-src 'self' data: www.owncloud.com;connect-src 'self';media-src 'self';frame-ancestors 'self';form-action 'self'"; + $expectedPolicy = "default-src 'none';base-uri 'none';manifest-src 'self';script-src 'self';script-src-elem 'strict-dynamic' 'self';style-src 'self' 'unsafe-inline';img-src 'self' data: blob:;font-src 'self' data: www.owncloud.com;connect-src 'self';media-src 'self';frame-ancestors 'self';form-action 'self'"; $this->contentSecurityPolicy->addAllowedFontDomain('www.owncloud.com'); $this->contentSecurityPolicy->disallowFontDomain('www.owncloud.org'); @@ -206,7 +206,7 @@ class ContentSecurityPolicyTest extends \Test\TestCase { } public function testGetPolicyDisallowFontDomainMultipleStakes() { - $expectedPolicy = "default-src 'none';base-uri 'none';manifest-src 'self';script-src 'self';style-src 'self' 'unsafe-inline';img-src 'self' data: blob:;font-src 'self' data:;connect-src 'self';media-src 'self';frame-ancestors 'self';form-action 'self'"; + $expectedPolicy = "default-src 'none';base-uri 'none';manifest-src 'self';script-src 'self';script-src-elem 'strict-dynamic' 'self';style-src 'self' 'unsafe-inline';img-src 'self' data: blob:;font-src 'self' data:;connect-src 'self';media-src 'self';frame-ancestors 'self';form-action 'self'"; $this->contentSecurityPolicy->addAllowedFontDomain('www.owncloud.com'); $this->contentSecurityPolicy->disallowFontDomain('www.owncloud.org')->disallowFontDomain('www.owncloud.com'); @@ -214,14 +214,14 @@ class ContentSecurityPolicyTest extends \Test\TestCase { } public function testGetPolicyConnectDomainValid() { - $expectedPolicy = "default-src 'none';base-uri 'none';manifest-src 'self';script-src 'self';style-src 'self' 'unsafe-inline';img-src 'self' data: blob:;font-src 'self' data:;connect-src 'self' www.owncloud.com;media-src 'self';frame-ancestors 'self';form-action 'self'"; + $expectedPolicy = "default-src 'none';base-uri 'none';manifest-src 'self';script-src 'self';script-src-elem 'strict-dynamic' 'self';style-src 'self' 'unsafe-inline';img-src 'self' data: blob:;font-src 'self' data:;connect-src 'self' www.owncloud.com;media-src 'self';frame-ancestors 'self';form-action 'self'"; $this->contentSecurityPolicy->addAllowedConnectDomain('www.owncloud.com'); $this->assertSame($expectedPolicy, $this->contentSecurityPolicy->buildPolicy()); } public function testGetPolicyConnectDomainValidMultiple() { - $expectedPolicy = "default-src 'none';base-uri 'none';manifest-src 'self';script-src 'self';style-src 'self' 'unsafe-inline';img-src 'self' data: blob:;font-src 'self' data:;connect-src 'self' www.owncloud.com www.owncloud.org;media-src 'self';frame-ancestors 'self';form-action 'self'"; + $expectedPolicy = "default-src 'none';base-uri 'none';manifest-src 'self';script-src 'self';script-src-elem 'strict-dynamic' 'self';style-src 'self' 'unsafe-inline';img-src 'self' data: blob:;font-src 'self' data:;connect-src 'self' www.owncloud.com www.owncloud.org;media-src 'self';frame-ancestors 'self';form-action 'self'"; $this->contentSecurityPolicy->addAllowedConnectDomain('www.owncloud.com'); $this->contentSecurityPolicy->addAllowedConnectDomain('www.owncloud.org'); @@ -229,7 +229,7 @@ class ContentSecurityPolicyTest extends \Test\TestCase { } public function testGetPolicyDisallowConnectDomain() { - $expectedPolicy = "default-src 'none';base-uri 'none';manifest-src 'self';script-src 'self';style-src 'self' 'unsafe-inline';img-src 'self' data: blob:;font-src 'self' data:;connect-src 'self';media-src 'self';frame-ancestors 'self';form-action 'self'"; + $expectedPolicy = "default-src 'none';base-uri 'none';manifest-src 'self';script-src 'self';script-src-elem 'strict-dynamic' 'self';style-src 'self' 'unsafe-inline';img-src 'self' data: blob:;font-src 'self' data:;connect-src 'self';media-src 'self';frame-ancestors 'self';form-action 'self'"; $this->contentSecurityPolicy->addAllowedConnectDomain('www.owncloud.com'); $this->contentSecurityPolicy->disallowConnectDomain('www.owncloud.com'); @@ -237,7 +237,7 @@ class ContentSecurityPolicyTest extends \Test\TestCase { } public function testGetPolicyDisallowConnectDomainMultiple() { - $expectedPolicy = "default-src 'none';base-uri 'none';manifest-src 'self';script-src 'self';style-src 'self' 'unsafe-inline';img-src 'self' data: blob:;font-src 'self' data:;connect-src 'self' www.owncloud.com;media-src 'self';frame-ancestors 'self';form-action 'self'"; + $expectedPolicy = "default-src 'none';base-uri 'none';manifest-src 'self';script-src 'self';script-src-elem 'strict-dynamic' 'self';style-src 'self' 'unsafe-inline';img-src 'self' data: blob:;font-src 'self' data:;connect-src 'self' www.owncloud.com;media-src 'self';frame-ancestors 'self';form-action 'self'"; $this->contentSecurityPolicy->addAllowedConnectDomain('www.owncloud.com'); $this->contentSecurityPolicy->disallowConnectDomain('www.owncloud.org'); @@ -245,7 +245,7 @@ class ContentSecurityPolicyTest extends \Test\TestCase { } public function testGetPolicyDisallowConnectDomainMultipleStakes() { - $expectedPolicy = "default-src 'none';base-uri 'none';manifest-src 'self';script-src 'self';style-src 'self' 'unsafe-inline';img-src 'self' data: blob:;font-src 'self' data:;connect-src 'self';media-src 'self';frame-ancestors 'self';form-action 'self'"; + $expectedPolicy = "default-src 'none';base-uri 'none';manifest-src 'self';script-src 'self';script-src-elem 'strict-dynamic' 'self';style-src 'self' 'unsafe-inline';img-src 'self' data: blob:;font-src 'self' data:;connect-src 'self';media-src 'self';frame-ancestors 'self';form-action 'self'"; $this->contentSecurityPolicy->addAllowedConnectDomain('www.owncloud.com'); $this->contentSecurityPolicy->disallowConnectDomain('www.owncloud.org')->disallowConnectDomain('www.owncloud.com'); @@ -253,14 +253,14 @@ class ContentSecurityPolicyTest extends \Test\TestCase { } public function testGetPolicyMediaDomainValid() { - $expectedPolicy = "default-src 'none';base-uri 'none';manifest-src 'self';script-src 'self';style-src 'self' 'unsafe-inline';img-src 'self' data: blob:;font-src 'self' data:;connect-src 'self';media-src 'self' www.owncloud.com;frame-ancestors 'self';form-action 'self'"; + $expectedPolicy = "default-src 'none';base-uri 'none';manifest-src 'self';script-src 'self';script-src-elem 'strict-dynamic' 'self';style-src 'self' 'unsafe-inline';img-src 'self' data: blob:;font-src 'self' data:;connect-src 'self';media-src 'self' www.owncloud.com;frame-ancestors 'self';form-action 'self'"; $this->contentSecurityPolicy->addAllowedMediaDomain('www.owncloud.com'); $this->assertSame($expectedPolicy, $this->contentSecurityPolicy->buildPolicy()); } public function testGetPolicyMediaDomainValidMultiple() { - $expectedPolicy = "default-src 'none';base-uri 'none';manifest-src 'self';script-src 'self';style-src 'self' 'unsafe-inline';img-src 'self' data: blob:;font-src 'self' data:;connect-src 'self';media-src 'self' www.owncloud.com www.owncloud.org;frame-ancestors 'self';form-action 'self'"; + $expectedPolicy = "default-src 'none';base-uri 'none';manifest-src 'self';script-src 'self';script-src-elem 'strict-dynamic' 'self';style-src 'self' 'unsafe-inline';img-src 'self' data: blob:;font-src 'self' data:;connect-src 'self';media-src 'self' www.owncloud.com www.owncloud.org;frame-ancestors 'self';form-action 'self'"; $this->contentSecurityPolicy->addAllowedMediaDomain('www.owncloud.com'); $this->contentSecurityPolicy->addAllowedMediaDomain('www.owncloud.org'); @@ -268,7 +268,7 @@ class ContentSecurityPolicyTest extends \Test\TestCase { } public function testGetPolicyDisallowMediaDomain() { - $expectedPolicy = "default-src 'none';base-uri 'none';manifest-src 'self';script-src 'self';style-src 'self' 'unsafe-inline';img-src 'self' data: blob:;font-src 'self' data:;connect-src 'self';media-src 'self';frame-ancestors 'self';form-action 'self'"; + $expectedPolicy = "default-src 'none';base-uri 'none';manifest-src 'self';script-src 'self';script-src-elem 'strict-dynamic' 'self';style-src 'self' 'unsafe-inline';img-src 'self' data: blob:;font-src 'self' data:;connect-src 'self';media-src 'self';frame-ancestors 'self';form-action 'self'"; $this->contentSecurityPolicy->addAllowedMediaDomain('www.owncloud.com'); $this->contentSecurityPolicy->disallowMediaDomain('www.owncloud.com'); @@ -276,7 +276,7 @@ class ContentSecurityPolicyTest extends \Test\TestCase { } public function testGetPolicyDisallowMediaDomainMultiple() { - $expectedPolicy = "default-src 'none';base-uri 'none';manifest-src 'self';script-src 'self';style-src 'self' 'unsafe-inline';img-src 'self' data: blob:;font-src 'self' data:;connect-src 'self';media-src 'self' www.owncloud.com;frame-ancestors 'self';form-action 'self'"; + $expectedPolicy = "default-src 'none';base-uri 'none';manifest-src 'self';script-src 'self';script-src-elem 'strict-dynamic' 'self';style-src 'self' 'unsafe-inline';img-src 'self' data: blob:;font-src 'self' data:;connect-src 'self';media-src 'self' www.owncloud.com;frame-ancestors 'self';form-action 'self'"; $this->contentSecurityPolicy->addAllowedMediaDomain('www.owncloud.com'); $this->contentSecurityPolicy->disallowMediaDomain('www.owncloud.org'); @@ -284,7 +284,7 @@ class ContentSecurityPolicyTest extends \Test\TestCase { } public function testGetPolicyDisallowMediaDomainMultipleStakes() { - $expectedPolicy = "default-src 'none';base-uri 'none';manifest-src 'self';script-src 'self';style-src 'self' 'unsafe-inline';img-src 'self' data: blob:;font-src 'self' data:;connect-src 'self';media-src 'self';frame-ancestors 'self';form-action 'self'"; + $expectedPolicy = "default-src 'none';base-uri 'none';manifest-src 'self';script-src 'self';script-src-elem 'strict-dynamic' 'self';style-src 'self' 'unsafe-inline';img-src 'self' data: blob:;font-src 'self' data:;connect-src 'self';media-src 'self';frame-ancestors 'self';form-action 'self'"; $this->contentSecurityPolicy->addAllowedMediaDomain('www.owncloud.com'); $this->contentSecurityPolicy->disallowMediaDomain('www.owncloud.org')->disallowMediaDomain('www.owncloud.com'); @@ -292,14 +292,14 @@ class ContentSecurityPolicyTest extends \Test\TestCase { } public function testGetPolicyObjectDomainValid() { - $expectedPolicy = "default-src 'none';base-uri 'none';manifest-src 'self';script-src 'self';style-src 'self' 'unsafe-inline';img-src 'self' data: blob:;font-src 'self' data:;connect-src 'self';media-src 'self';object-src www.owncloud.com;frame-ancestors 'self';form-action 'self'"; + $expectedPolicy = "default-src 'none';base-uri 'none';manifest-src 'self';script-src 'self';script-src-elem 'strict-dynamic' 'self';style-src 'self' 'unsafe-inline';img-src 'self' data: blob:;font-src 'self' data:;connect-src 'self';media-src 'self';object-src www.owncloud.com;frame-ancestors 'self';form-action 'self'"; $this->contentSecurityPolicy->addAllowedObjectDomain('www.owncloud.com'); $this->assertSame($expectedPolicy, $this->contentSecurityPolicy->buildPolicy()); } public function testGetPolicyObjectDomainValidMultiple() { - $expectedPolicy = "default-src 'none';base-uri 'none';manifest-src 'self';script-src 'self';style-src 'self' 'unsafe-inline';img-src 'self' data: blob:;font-src 'self' data:;connect-src 'self';media-src 'self';object-src www.owncloud.com www.owncloud.org;frame-ancestors 'self';form-action 'self'"; + $expectedPolicy = "default-src 'none';base-uri 'none';manifest-src 'self';script-src 'self';script-src-elem 'strict-dynamic' 'self';style-src 'self' 'unsafe-inline';img-src 'self' data: blob:;font-src 'self' data:;connect-src 'self';media-src 'self';object-src www.owncloud.com www.owncloud.org;frame-ancestors 'self';form-action 'self'"; $this->contentSecurityPolicy->addAllowedObjectDomain('www.owncloud.com'); $this->contentSecurityPolicy->addAllowedObjectDomain('www.owncloud.org'); @@ -307,7 +307,7 @@ class ContentSecurityPolicyTest extends \Test\TestCase { } public function testGetPolicyDisallowObjectDomain() { - $expectedPolicy = "default-src 'none';base-uri 'none';manifest-src 'self';script-src 'self';style-src 'self' 'unsafe-inline';img-src 'self' data: blob:;font-src 'self' data:;connect-src 'self';media-src 'self';frame-ancestors 'self';form-action 'self'"; + $expectedPolicy = "default-src 'none';base-uri 'none';manifest-src 'self';script-src 'self';script-src-elem 'strict-dynamic' 'self';style-src 'self' 'unsafe-inline';img-src 'self' data: blob:;font-src 'self' data:;connect-src 'self';media-src 'self';frame-ancestors 'self';form-action 'self'"; $this->contentSecurityPolicy->addAllowedObjectDomain('www.owncloud.com'); $this->contentSecurityPolicy->disallowObjectDomain('www.owncloud.com'); @@ -315,7 +315,7 @@ class ContentSecurityPolicyTest extends \Test\TestCase { } public function testGetPolicyDisallowObjectDomainMultiple() { - $expectedPolicy = "default-src 'none';base-uri 'none';manifest-src 'self';script-src 'self';style-src 'self' 'unsafe-inline';img-src 'self' data: blob:;font-src 'self' data:;connect-src 'self';media-src 'self';object-src www.owncloud.com;frame-ancestors 'self';form-action 'self'"; + $expectedPolicy = "default-src 'none';base-uri 'none';manifest-src 'self';script-src 'self';script-src-elem 'strict-dynamic' 'self';style-src 'self' 'unsafe-inline';img-src 'self' data: blob:;font-src 'self' data:;connect-src 'self';media-src 'self';object-src www.owncloud.com;frame-ancestors 'self';form-action 'self'"; $this->contentSecurityPolicy->addAllowedObjectDomain('www.owncloud.com'); $this->contentSecurityPolicy->disallowObjectDomain('www.owncloud.org'); @@ -323,7 +323,7 @@ class ContentSecurityPolicyTest extends \Test\TestCase { } public function testGetPolicyDisallowObjectDomainMultipleStakes() { - $expectedPolicy = "default-src 'none';base-uri 'none';manifest-src 'self';script-src 'self';style-src 'self' 'unsafe-inline';img-src 'self' data: blob:;font-src 'self' data:;connect-src 'self';media-src 'self';frame-ancestors 'self';form-action 'self'"; + $expectedPolicy = "default-src 'none';base-uri 'none';manifest-src 'self';script-src 'self';script-src-elem 'strict-dynamic' 'self';style-src 'self' 'unsafe-inline';img-src 'self' data: blob:;font-src 'self' data:;connect-src 'self';media-src 'self';frame-ancestors 'self';form-action 'self'"; $this->contentSecurityPolicy->addAllowedObjectDomain('www.owncloud.com'); $this->contentSecurityPolicy->disallowObjectDomain('www.owncloud.org')->disallowObjectDomain('www.owncloud.com'); @@ -331,14 +331,14 @@ class ContentSecurityPolicyTest extends \Test\TestCase { } public function testGetAllowedFrameDomain() { - $expectedPolicy = "default-src 'none';base-uri 'none';manifest-src 'self';script-src 'self';style-src 'self' 'unsafe-inline';img-src 'self' data: blob:;font-src 'self' data:;connect-src 'self';media-src 'self';frame-src www.owncloud.com;frame-ancestors 'self';form-action 'self'"; + $expectedPolicy = "default-src 'none';base-uri 'none';manifest-src 'self';script-src 'self';script-src-elem 'strict-dynamic' 'self';style-src 'self' 'unsafe-inline';img-src 'self' data: blob:;font-src 'self' data:;connect-src 'self';media-src 'self';frame-src www.owncloud.com;frame-ancestors 'self';form-action 'self'"; $this->contentSecurityPolicy->addAllowedFrameDomain('www.owncloud.com'); $this->assertSame($expectedPolicy, $this->contentSecurityPolicy->buildPolicy()); } public function testGetPolicyFrameDomainValidMultiple() { - $expectedPolicy = "default-src 'none';base-uri 'none';manifest-src 'self';script-src 'self';style-src 'self' 'unsafe-inline';img-src 'self' data: blob:;font-src 'self' data:;connect-src 'self';media-src 'self';frame-src www.owncloud.com www.owncloud.org;frame-ancestors 'self';form-action 'self'"; + $expectedPolicy = "default-src 'none';base-uri 'none';manifest-src 'self';script-src 'self';script-src-elem 'strict-dynamic' 'self';style-src 'self' 'unsafe-inline';img-src 'self' data: blob:;font-src 'self' data:;connect-src 'self';media-src 'self';frame-src www.owncloud.com www.owncloud.org;frame-ancestors 'self';form-action 'self'"; $this->contentSecurityPolicy->addAllowedFrameDomain('www.owncloud.com'); $this->contentSecurityPolicy->addAllowedFrameDomain('www.owncloud.org'); @@ -346,7 +346,7 @@ class ContentSecurityPolicyTest extends \Test\TestCase { } public function testGetPolicyDisallowFrameDomain() { - $expectedPolicy = "default-src 'none';base-uri 'none';manifest-src 'self';script-src 'self';style-src 'self' 'unsafe-inline';img-src 'self' data: blob:;font-src 'self' data:;connect-src 'self';media-src 'self';frame-ancestors 'self';form-action 'self'"; + $expectedPolicy = "default-src 'none';base-uri 'none';manifest-src 'self';script-src 'self';script-src-elem 'strict-dynamic' 'self';style-src 'self' 'unsafe-inline';img-src 'self' data: blob:;font-src 'self' data:;connect-src 'self';media-src 'self';frame-ancestors 'self';form-action 'self'"; $this->contentSecurityPolicy->addAllowedFrameDomain('www.owncloud.com'); $this->contentSecurityPolicy->disallowFrameDomain('www.owncloud.com'); @@ -354,7 +354,7 @@ class ContentSecurityPolicyTest extends \Test\TestCase { } public function testGetPolicyDisallowFrameDomainMultiple() { - $expectedPolicy = "default-src 'none';base-uri 'none';manifest-src 'self';script-src 'self';style-src 'self' 'unsafe-inline';img-src 'self' data: blob:;font-src 'self' data:;connect-src 'self';media-src 'self';frame-src www.owncloud.com;frame-ancestors 'self';form-action 'self'"; + $expectedPolicy = "default-src 'none';base-uri 'none';manifest-src 'self';script-src 'self';script-src-elem 'strict-dynamic' 'self';style-src 'self' 'unsafe-inline';img-src 'self' data: blob:;font-src 'self' data:;connect-src 'self';media-src 'self';frame-src www.owncloud.com;frame-ancestors 'self';form-action 'self'"; $this->contentSecurityPolicy->addAllowedFrameDomain('www.owncloud.com'); $this->contentSecurityPolicy->disallowFrameDomain('www.owncloud.org'); @@ -362,7 +362,7 @@ class ContentSecurityPolicyTest extends \Test\TestCase { } public function testGetPolicyDisallowFrameDomainMultipleStakes() { - $expectedPolicy = "default-src 'none';base-uri 'none';manifest-src 'self';script-src 'self';style-src 'self' 'unsafe-inline';img-src 'self' data: blob:;font-src 'self' data:;connect-src 'self';media-src 'self';frame-ancestors 'self';form-action 'self'"; + $expectedPolicy = "default-src 'none';base-uri 'none';manifest-src 'self';script-src 'self';script-src-elem 'strict-dynamic' 'self';style-src 'self' 'unsafe-inline';img-src 'self' data: blob:;font-src 'self' data:;connect-src 'self';media-src 'self';frame-ancestors 'self';form-action 'self'"; $this->contentSecurityPolicy->addAllowedFrameDomain('www.owncloud.com'); $this->contentSecurityPolicy->disallowFrameDomain('www.owncloud.org')->disallowFrameDomain('www.owncloud.com'); @@ -370,14 +370,14 @@ class ContentSecurityPolicyTest extends \Test\TestCase { } public function testGetAllowedChildSrcDomain() { - $expectedPolicy = "default-src 'none';base-uri 'none';manifest-src 'self';script-src 'self';style-src 'self' 'unsafe-inline';img-src 'self' data: blob:;font-src 'self' data:;connect-src 'self';media-src 'self';child-src child.owncloud.com;frame-ancestors 'self';form-action 'self'"; + $expectedPolicy = "default-src 'none';base-uri 'none';manifest-src 'self';script-src 'self';script-src-elem 'strict-dynamic' 'self';style-src 'self' 'unsafe-inline';img-src 'self' data: blob:;font-src 'self' data:;connect-src 'self';media-src 'self';child-src child.owncloud.com;frame-ancestors 'self';form-action 'self'"; $this->contentSecurityPolicy->addAllowedChildSrcDomain('child.owncloud.com'); $this->assertSame($expectedPolicy, $this->contentSecurityPolicy->buildPolicy()); } public function testGetPolicyChildSrcValidMultiple() { - $expectedPolicy = "default-src 'none';base-uri 'none';manifest-src 'self';script-src 'self';style-src 'self' 'unsafe-inline';img-src 'self' data: blob:;font-src 'self' data:;connect-src 'self';media-src 'self';child-src child.owncloud.com child.owncloud.org;frame-ancestors 'self';form-action 'self'"; + $expectedPolicy = "default-src 'none';base-uri 'none';manifest-src 'self';script-src 'self';script-src-elem 'strict-dynamic' 'self';style-src 'self' 'unsafe-inline';img-src 'self' data: blob:;font-src 'self' data:;connect-src 'self';media-src 'self';child-src child.owncloud.com child.owncloud.org;frame-ancestors 'self';form-action 'self'"; $this->contentSecurityPolicy->addAllowedChildSrcDomain('child.owncloud.com'); $this->contentSecurityPolicy->addAllowedChildSrcDomain('child.owncloud.org'); @@ -385,7 +385,7 @@ class ContentSecurityPolicyTest extends \Test\TestCase { } public function testGetPolicyDisallowChildSrcDomain() { - $expectedPolicy = "default-src 'none';base-uri 'none';manifest-src 'self';script-src 'self';style-src 'self' 'unsafe-inline';img-src 'self' data: blob:;font-src 'self' data:;connect-src 'self';media-src 'self';frame-ancestors 'self';form-action 'self'"; + $expectedPolicy = "default-src 'none';base-uri 'none';manifest-src 'self';script-src 'self';script-src-elem 'strict-dynamic' 'self';style-src 'self' 'unsafe-inline';img-src 'self' data: blob:;font-src 'self' data:;connect-src 'self';media-src 'self';frame-ancestors 'self';form-action 'self'"; $this->contentSecurityPolicy->addAllowedChildSrcDomain('www.owncloud.com'); $this->contentSecurityPolicy->disallowChildSrcDomain('www.owncloud.com'); @@ -393,7 +393,7 @@ class ContentSecurityPolicyTest extends \Test\TestCase { } public function testGetPolicyDisallowChildSrcDomainMultiple() { - $expectedPolicy = "default-src 'none';base-uri 'none';manifest-src 'self';script-src 'self';style-src 'self' 'unsafe-inline';img-src 'self' data: blob:;font-src 'self' data:;connect-src 'self';media-src 'self';child-src www.owncloud.com;frame-ancestors 'self';form-action 'self'"; + $expectedPolicy = "default-src 'none';base-uri 'none';manifest-src 'self';script-src 'self';script-src-elem 'strict-dynamic' 'self';style-src 'self' 'unsafe-inline';img-src 'self' data: blob:;font-src 'self' data:;connect-src 'self';media-src 'self';child-src www.owncloud.com;frame-ancestors 'self';form-action 'self'"; $this->contentSecurityPolicy->addAllowedChildSrcDomain('www.owncloud.com'); $this->contentSecurityPolicy->disallowChildSrcDomain('www.owncloud.org'); @@ -401,7 +401,7 @@ class ContentSecurityPolicyTest extends \Test\TestCase { } public function testGetPolicyDisallowChildSrcDomainMultipleStakes() { - $expectedPolicy = "default-src 'none';base-uri 'none';manifest-src 'self';script-src 'self';style-src 'self' 'unsafe-inline';img-src 'self' data: blob:;font-src 'self' data:;connect-src 'self';media-src 'self';frame-ancestors 'self';form-action 'self'"; + $expectedPolicy = "default-src 'none';base-uri 'none';manifest-src 'self';script-src 'self';script-src-elem 'strict-dynamic' 'self';style-src 'self' 'unsafe-inline';img-src 'self' data: blob:;font-src 'self' data:;connect-src 'self';media-src 'self';frame-ancestors 'self';form-action 'self'"; $this->contentSecurityPolicy->addAllowedChildSrcDomain('www.owncloud.com'); $this->contentSecurityPolicy->disallowChildSrcDomain('www.owncloud.org')->disallowChildSrcDomain('www.owncloud.com'); @@ -411,14 +411,14 @@ class ContentSecurityPolicyTest extends \Test\TestCase { public function testGetAllowedFrameAncestorDomain() { - $expectedPolicy = "default-src 'none';base-uri 'none';manifest-src 'self';script-src 'self';style-src 'self' 'unsafe-inline';img-src 'self' data: blob:;font-src 'self' data:;connect-src 'self';media-src 'self';frame-ancestors 'self' sub.nextcloud.com;form-action 'self'"; + $expectedPolicy = "default-src 'none';base-uri 'none';manifest-src 'self';script-src 'self';script-src-elem 'strict-dynamic' 'self';style-src 'self' 'unsafe-inline';img-src 'self' data: blob:;font-src 'self' data:;connect-src 'self';media-src 'self';frame-ancestors 'self' sub.nextcloud.com;form-action 'self'"; $this->contentSecurityPolicy->addAllowedFrameAncestorDomain('sub.nextcloud.com'); $this->assertSame($expectedPolicy, $this->contentSecurityPolicy->buildPolicy()); } public function testGetPolicyFrameAncestorValidMultiple() { - $expectedPolicy = "default-src 'none';base-uri 'none';manifest-src 'self';script-src 'self';style-src 'self' 'unsafe-inline';img-src 'self' data: blob:;font-src 'self' data:;connect-src 'self';media-src 'self';frame-ancestors 'self' sub.nextcloud.com foo.nextcloud.com;form-action 'self'"; + $expectedPolicy = "default-src 'none';base-uri 'none';manifest-src 'self';script-src 'self';script-src-elem 'strict-dynamic' 'self';style-src 'self' 'unsafe-inline';img-src 'self' data: blob:;font-src 'self' data:;connect-src 'self';media-src 'self';frame-ancestors 'self' sub.nextcloud.com foo.nextcloud.com;form-action 'self'"; $this->contentSecurityPolicy->addAllowedFrameAncestorDomain('sub.nextcloud.com'); $this->contentSecurityPolicy->addAllowedFrameAncestorDomain('foo.nextcloud.com'); @@ -426,7 +426,7 @@ class ContentSecurityPolicyTest extends \Test\TestCase { } public function testGetPolicyDisallowFrameAncestorDomain() { - $expectedPolicy = "default-src 'none';base-uri 'none';manifest-src 'self';script-src 'self';style-src 'self' 'unsafe-inline';img-src 'self' data: blob:;font-src 'self' data:;connect-src 'self';media-src 'self';frame-ancestors 'self';form-action 'self'"; + $expectedPolicy = "default-src 'none';base-uri 'none';manifest-src 'self';script-src 'self';script-src-elem 'strict-dynamic' 'self';style-src 'self' 'unsafe-inline';img-src 'self' data: blob:;font-src 'self' data:;connect-src 'self';media-src 'self';frame-ancestors 'self';form-action 'self'"; $this->contentSecurityPolicy->addAllowedFrameAncestorDomain('www.nextcloud.com'); $this->contentSecurityPolicy->disallowFrameAncestorDomain('www.nextcloud.com'); @@ -434,7 +434,7 @@ class ContentSecurityPolicyTest extends \Test\TestCase { } public function testGetPolicyDisallowFrameAncestorDomainMultiple() { - $expectedPolicy = "default-src 'none';base-uri 'none';manifest-src 'self';script-src 'self';style-src 'self' 'unsafe-inline';img-src 'self' data: blob:;font-src 'self' data:;connect-src 'self';media-src 'self';frame-ancestors 'self' www.nextcloud.com;form-action 'self'"; + $expectedPolicy = "default-src 'none';base-uri 'none';manifest-src 'self';script-src 'self';script-src-elem 'strict-dynamic' 'self';style-src 'self' 'unsafe-inline';img-src 'self' data: blob:;font-src 'self' data:;connect-src 'self';media-src 'self';frame-ancestors 'self' www.nextcloud.com;form-action 'self'"; $this->contentSecurityPolicy->addAllowedFrameAncestorDomain('www.nextcloud.com'); $this->contentSecurityPolicy->disallowFrameAncestorDomain('www.nextcloud.org'); @@ -442,7 +442,7 @@ class ContentSecurityPolicyTest extends \Test\TestCase { } public function testGetPolicyDisallowFrameAncestorDomainMultipleStakes() { - $expectedPolicy = "default-src 'none';base-uri 'none';manifest-src 'self';script-src 'self';style-src 'self' 'unsafe-inline';img-src 'self' data: blob:;font-src 'self' data:;connect-src 'self';media-src 'self';frame-ancestors 'self';form-action 'self'"; + $expectedPolicy = "default-src 'none';base-uri 'none';manifest-src 'self';script-src 'self';script-src-elem 'strict-dynamic' 'self';style-src 'self' 'unsafe-inline';img-src 'self' data: blob:;font-src 'self' data:;connect-src 'self';media-src 'self';frame-ancestors 'self';form-action 'self'"; $this->contentSecurityPolicy->addAllowedChildSrcDomain('www.owncloud.com'); $this->contentSecurityPolicy->disallowChildSrcDomain('www.owncloud.org')->disallowChildSrcDomain('www.owncloud.com'); @@ -450,14 +450,14 @@ class ContentSecurityPolicyTest extends \Test\TestCase { } public function testGetPolicyUnsafeEval() { - $expectedPolicy = "default-src 'none';base-uri 'none';manifest-src 'self';script-src 'self' 'unsafe-eval';style-src 'self' 'unsafe-inline';img-src 'self' data: blob:;font-src 'self' data:;connect-src 'self';media-src 'self';frame-ancestors 'self';form-action 'self'"; + $expectedPolicy = "default-src 'none';base-uri 'none';manifest-src 'self';script-src 'self' 'unsafe-eval';script-src-elem 'strict-dynamic' 'self' 'unsafe-eval';style-src 'self' 'unsafe-inline';img-src 'self' data: blob:;font-src 'self' data:;connect-src 'self';media-src 'self';frame-ancestors 'self';form-action 'self'"; $this->contentSecurityPolicy->allowEvalScript(true); $this->assertSame($expectedPolicy, $this->contentSecurityPolicy->buildPolicy()); } public function testGetPolicyUnsafeWasmEval() { - $expectedPolicy = "default-src 'none';base-uri 'none';manifest-src 'self';script-src 'self' 'wasm-unsafe-eval';style-src 'self' 'unsafe-inline';img-src 'self' data: blob:;font-src 'self' data:;connect-src 'self';media-src 'self';frame-ancestors 'self';form-action 'self'"; + $expectedPolicy = "default-src 'none';base-uri 'none';manifest-src 'self';script-src 'self' 'wasm-unsafe-eval';script-src-elem 'strict-dynamic' 'self' 'wasm-unsafe-eval';style-src 'self' 'unsafe-inline';img-src 'self' data: blob:;font-src 'self' data:;connect-src 'self';media-src 'self';frame-ancestors 'self';form-action 'self'"; $this->contentSecurityPolicy->allowEvalWasm(true); $this->assertSame($expectedPolicy, $this->contentSecurityPolicy->buildPolicy()); @@ -468,6 +468,15 @@ class ContentSecurityPolicyTest extends \Test\TestCase { $expectedPolicy = "default-src 'none';base-uri 'none';manifest-src 'self';script-src 'nonce-".base64_encode($nonce) . "';style-src 'self' 'unsafe-inline';img-src 'self' data: blob:;font-src 'self' data:;connect-src 'self';media-src 'self';frame-ancestors 'self';form-action 'self'"; $this->contentSecurityPolicy->useJsNonce($nonce); + $this->contentSecurityPolicy->useStrictDynamicOnScripts(false); + $this->assertSame($expectedPolicy, $this->contentSecurityPolicy->buildPolicy()); + } + + public function testGetPolicyNonceDefault() { + $nonce = 'my-nonce'; + $expectedPolicy = "default-src 'none';base-uri 'none';manifest-src 'self';script-src 'nonce-".base64_encode($nonce) . "';script-src-elem 'strict-dynamic' 'nonce-".base64_encode($nonce) . "';style-src 'self' 'unsafe-inline';img-src 'self' data: blob:;font-src 'self' data:;connect-src 'self';media-src 'self';frame-ancestors 'self';form-action 'self'"; + + $this->contentSecurityPolicy->useJsNonce($nonce); $this->assertSame($expectedPolicy, $this->contentSecurityPolicy->buildPolicy()); } @@ -477,6 +486,31 @@ class ContentSecurityPolicyTest extends \Test\TestCase { $this->contentSecurityPolicy->useJsNonce($nonce); $this->contentSecurityPolicy->useStrictDynamic(true); + $this->contentSecurityPolicy->useStrictDynamicOnScripts(false); + $this->assertSame($expectedPolicy, $this->contentSecurityPolicy->buildPolicy()); + } + + public function testGetPolicyNonceStrictDynamicDefault() { + $nonce = 'my-nonce'; + $expectedPolicy = "default-src 'none';base-uri 'none';manifest-src 'self';script-src 'strict-dynamic' 'nonce-".base64_encode($nonce) . "';style-src 'self' 'unsafe-inline';img-src 'self' data: blob:;font-src 'self' data:;connect-src 'self';media-src 'self';frame-ancestors 'self';form-action 'self'"; + + $this->contentSecurityPolicy->useJsNonce($nonce); + $this->contentSecurityPolicy->useStrictDynamic(true); + $this->assertSame($expectedPolicy, $this->contentSecurityPolicy->buildPolicy()); + } + + public function testGetPolicyStrictDynamicOnScriptsOff() { + $expectedPolicy = "default-src 'none';base-uri 'none';manifest-src 'self';script-src 'self';style-src 'self' 'unsafe-inline';img-src 'self' data: blob:;font-src 'self' data:;connect-src 'self';media-src 'self';frame-ancestors 'self';form-action 'self'"; + + $this->contentSecurityPolicy->useStrictDynamicOnScripts(false); + $this->assertSame($expectedPolicy, $this->contentSecurityPolicy->buildPolicy()); + } + + public function testGetPolicyStrictDynamicAndStrictDynamicOnScripts() { + $expectedPolicy = "default-src 'none';base-uri 'none';manifest-src 'self';script-src 'self';script-src-elem 'strict-dynamic' 'self';style-src 'self' 'unsafe-inline';img-src 'self' data: blob:;font-src 'self' data:;connect-src 'self';media-src 'self';frame-ancestors 'self';form-action 'self'"; + + $this->contentSecurityPolicy->useStrictDynamic(true); + $this->contentSecurityPolicy->useStrictDynamicOnScripts(true); $this->assertSame($expectedPolicy, $this->contentSecurityPolicy->buildPolicy()); } } diff --git a/tests/lib/AppFramework/Http/EmptyContentSecurityPolicyTest.php b/tests/lib/AppFramework/Http/EmptyContentSecurityPolicyTest.php index 328e464f981..31fc2ffc785 100644 --- a/tests/lib/AppFramework/Http/EmptyContentSecurityPolicyTest.php +++ b/tests/lib/AppFramework/Http/EmptyContentSecurityPolicyTest.php @@ -425,6 +425,42 @@ class EmptyContentSecurityPolicyTest extends \Test\TestCase { $this->assertSame($expectedPolicy, $this->contentSecurityPolicy->buildPolicy()); } + public function testGetPolicyWithJsNonceAndStrictDynamic() { + $expectedPolicy = "default-src 'none';base-uri 'none';manifest-src 'self';script-src 'strict-dynamic' 'nonce-TXlKc05vbmNl' www.nextcloud.com;frame-ancestors 'none'"; + + $this->contentSecurityPolicy->addAllowedScriptDomain('www.nextcloud.com'); + $this->contentSecurityPolicy->useStrictDynamic(true); + $this->contentSecurityPolicy->useJsNonce('MyJsNonce'); + $this->assertSame($expectedPolicy, $this->contentSecurityPolicy->buildPolicy()); + } + + public function testGetPolicyWithJsNonceAndStrictDynamicAndStrictDynamicOnScripts() { + $expectedPolicy = "default-src 'none';base-uri 'none';manifest-src 'self';script-src 'strict-dynamic' 'nonce-TXlKc05vbmNl' www.nextcloud.com;frame-ancestors 'none'"; + + $this->contentSecurityPolicy->addAllowedScriptDomain('www.nextcloud.com'); + $this->contentSecurityPolicy->useStrictDynamic(true); + $this->contentSecurityPolicy->useStrictDynamicOnScripts(true); + $this->contentSecurityPolicy->useJsNonce('MyJsNonce'); + // Should be same as `testGetPolicyWithJsNonceAndStrictDynamic` because of fallback + $this->assertSame($expectedPolicy, $this->contentSecurityPolicy->buildPolicy()); + } + + public function testGetPolicyWithJsNonceAndStrictDynamicOnScripts() { + $expectedPolicy = "default-src 'none';base-uri 'none';manifest-src 'self';script-src 'nonce-TXlKc05vbmNl' www.nextcloud.com;script-src-elem 'strict-dynamic' 'nonce-TXlKc05vbmNl' www.nextcloud.com;frame-ancestors 'none'"; + + $this->contentSecurityPolicy->addAllowedScriptDomain('www.nextcloud.com'); + $this->contentSecurityPolicy->useStrictDynamicOnScripts(true); + $this->contentSecurityPolicy->useJsNonce('MyJsNonce'); + $this->assertSame($expectedPolicy, $this->contentSecurityPolicy->buildPolicy()); + } + + public function testGetPolicyWithStrictDynamicOnScripts() { + $expectedPolicy = "default-src 'none';base-uri 'none';manifest-src 'self';script-src-elem 'strict-dynamic' ;frame-ancestors 'none'"; + + $this->contentSecurityPolicy->useStrictDynamicOnScripts(true); + $this->assertSame($expectedPolicy, $this->contentSecurityPolicy->buildPolicy()); + } + public function testGetPolicyWithJsNonceAndSelfScriptDomain() { $expectedPolicy = "default-src 'none';base-uri 'none';manifest-src 'self';script-src 'nonce-TXlKc05vbmNl';frame-ancestors 'none'"; diff --git a/tests/lib/Security/CSP/ContentSecurityPolicyManagerTest.php b/tests/lib/Security/CSP/ContentSecurityPolicyManagerTest.php index 24acd3cabc9..0af73f10c65 100644 --- a/tests/lib/Security/CSP/ContentSecurityPolicyManagerTest.php +++ b/tests/lib/Security/CSP/ContentSecurityPolicyManagerTest.php @@ -72,7 +72,7 @@ class ContentSecurityPolicyManagerTest extends TestCase { $expected->addAllowedImageDomain('anotherdomain.de'); $expected->addAllowedImageDomain('example.org'); $expected->addAllowedChildSrcDomain('childdomain'); - $expectedStringPolicy = "default-src 'none';base-uri 'none';manifest-src 'self';script-src 'self' 'unsafe-eval';style-src 'self' 'unsafe-inline';img-src 'self' data: blob: anotherdomain.de example.org;font-src 'self' data: mydomain.com example.com anotherFontDomain;connect-src 'self';media-src 'self';child-src childdomain;frame-ancestors 'self';form-action 'self' thirdDomain"; + $expectedStringPolicy = "default-src 'none';base-uri 'none';manifest-src 'self';script-src 'self' 'unsafe-eval';script-src-elem 'strict-dynamic' 'self' 'unsafe-eval';style-src 'self' 'unsafe-inline';img-src 'self' data: blob: anotherdomain.de example.org;font-src 'self' data: mydomain.com example.com anotherFontDomain;connect-src 'self';media-src 'self';child-src childdomain;frame-ancestors 'self';form-action 'self' thirdDomain"; $this->assertEquals($expected, $this->contentSecurityPolicyManager->getDefaultPolicy()); $this->assertSame($expectedStringPolicy, $this->contentSecurityPolicyManager->getDefaultPolicy()->buildPolicy()); @@ -115,7 +115,7 @@ class ContentSecurityPolicyManagerTest extends TestCase { $expected->addAllowedChildSrcDomain('childdomain'); $expected->addAllowedFormActionDomain('thirdDomain'); $expected->useStrictDynamic(true); - $expectedStringPolicy = "default-src 'none';base-uri 'none';manifest-src 'self';script-src 'self' 'unsafe-eval';style-src 'self' 'unsafe-inline';img-src 'self' data: blob: anotherdomain.de example.org;font-src 'self' data: mydomain.com example.com anotherFontDomain;connect-src 'self';media-src 'self';child-src childdomain;frame-ancestors 'self';form-action 'self' thirdDomain"; + $expectedStringPolicy = "default-src 'none';base-uri 'none';manifest-src 'self';script-src 'self' 'unsafe-eval';script-src-elem 'strict-dynamic' 'self' 'unsafe-eval';style-src 'self' 'unsafe-inline';img-src 'self' data: blob: anotherdomain.de example.org;font-src 'self' data: mydomain.com example.com anotherFontDomain;connect-src 'self';media-src 'self';child-src childdomain;frame-ancestors 'self';form-action 'self' thirdDomain"; $this->assertEquals($expected, $this->contentSecurityPolicyManager->getDefaultPolicy()); $this->assertSame($expectedStringPolicy, $this->contentSecurityPolicyManager->getDefaultPolicy()->buildPolicy()); |