From 935fd43592302571d46ff15a7aad2965296484ff Mon Sep 17 00:00:00 2001 From: Oliver Hader <oliver@typo3.org> Date: Thu, 4 May 2023 14:16:06 +0200 Subject: [PATCH] [BUGFIX] Correctly represent CSP UriValue('*') An entire wildcard `UriValue`, which is just `'*'`, was incorrectly encoded. In the scope of CSP `'*'` is valid. Using wildcards should be avoided in favor of being specific. Resolves: #100798 Releases: main, 12.4 Change-Id: Iaf13b1d2095a672653894a6da5f10ad7115a2538 Reviewed-on: https://review.typo3.org/c/Packages/TYPO3.CMS/+/78933 Tested-by: Nikita Hovratov <nikita.h@live.de> Tested-by: core-ci <typo3@b13.com> Reviewed-by: Nikita Hovratov <nikita.h@live.de> Reviewed-by: Benni Mack <benni@typo3.org> Reviewed-by: Oliver Hader <oliver.hader@typo3.org> Tested-by: Georg Ringer <georg.ringer@gmail.com> Tested-by: Benni Mack <benni@typo3.org> Tested-by: Oliver Hader <oliver.hader@typo3.org> Reviewed-by: Georg Ringer <georg.ringer@gmail.com> --- .../Security/ContentSecurityPolicy/UriValue.php | 12 ++++++++++++ .../Security/ContentSecurityPolicy/UriValueTest.php | 3 +++ 2 files changed, 15 insertions(+) diff --git a/typo3/sysext/core/Classes/Security/ContentSecurityPolicy/UriValue.php b/typo3/sysext/core/Classes/Security/ContentSecurityPolicy/UriValue.php index 3dd292a00428..ed460a49e65c 100644 --- a/typo3/sysext/core/Classes/Security/ContentSecurityPolicy/UriValue.php +++ b/typo3/sysext/core/Classes/Security/ContentSecurityPolicy/UriValue.php @@ -28,6 +28,7 @@ use TYPO3\CMS\Core\Http\Uri; final class UriValue extends Uri implements \Stringable, EqualityInterface, CoveringInterface, SourceInterface { private string $domainName = ''; + private bool $entireWildcard = false; private bool $domainWildcard = false; public static function fromUri(UriInterface $other): self @@ -37,6 +38,9 @@ final class UriValue extends Uri implements \Stringable, EqualityInterface, Cove public function __toString(): string { + if ($this->entireWildcard) { + return '*'; + } if ($this->domainName !== '') { return ($this->domainWildcard ? '*.' : '') . $this->domainName; } @@ -53,6 +57,10 @@ final class UriValue extends Uri implements \Stringable, EqualityInterface, Cove if (!$other instanceof self) { return false; } + // `*` matches anything + if ($this->entireWildcard) { + return true; + } // `*.example.com` or `example.com` if ($this->domainName !== '') { if ($this->domainWildcard) { @@ -87,6 +95,10 @@ final class UriValue extends Uri implements \Stringable, EqualityInterface, Cove protected function parseUri(string $uri): void { + if ($uri === '*') { + $this->entireWildcard = true; + return; + } parent::parseUri($uri); // ignore fragments per default $this->fragment = ''; diff --git a/typo3/sysext/core/Tests/Unit/Security/ContentSecurityPolicy/UriValueTest.php b/typo3/sysext/core/Tests/Unit/Security/ContentSecurityPolicy/UriValueTest.php index 5a6063a99946..a9382743fbd0 100644 --- a/typo3/sysext/core/Tests/Unit/Security/ContentSecurityPolicy/UriValueTest.php +++ b/typo3/sysext/core/Tests/Unit/Security/ContentSecurityPolicy/UriValueTest.php @@ -40,6 +40,7 @@ final class UriValueTest extends UnitTestCase yield ['//www.typo3.org']; yield ['www.typo3.org']; yield ['*.typo3.org']; + yield ['*']; // expected behavior, falls back to upstream parser´ // (since e.g. query-param is given, which is not expected here in the scope of CSP with `UriValue`) @@ -83,6 +84,7 @@ final class UriValueTest extends UnitTestCase yield ['example.com/path', 'example.com/path', true]; yield ['example.com/path', 'example.com/other', false]; yield ['*.example.com', '*.example.com', true]; + yield ['*', '*.example.com', true]; yield ['https://example.com/', 'https://example.com/path/file.css', true]; yield ['example.com', 'https://example.com/path/file.css', true]; @@ -94,6 +96,7 @@ final class UriValueTest extends UnitTestCase yield ['*.sub.example.com', 'example.com', false]; yield ['sub.example.com', '*.example.com', false]; yield ['*.sub.example.com', '*.example.com', false]; + yield ['*.example.com', '*', false]; } /** -- GitLab