Skip to content
Snippets Groups Projects
Commit 4331cf82 authored by Oliver Hader's avatar Oliver Hader Committed by Oliver Hader
Browse files

[BUGFIX] Allow assigning empty sources to non-empty CSP directives

Prior to this change, empty sources to be assigned to an
existing Content-Security-Policy directive have been ignored.

Resolves: #104727
Releases: main, 12.4
Change-Id: I788c32a1772d929b2b974058b0afb746d936718c
Reviewed-on: https://review.typo3.org/c/Packages/TYPO3.CMS/+/85812


Reviewed-by: default avatarOliver Hader <oliver.hader@typo3.org>
Tested-by: default avatarcore-ci <typo3@b13.com>
Reviewed-by: default avatarChris Müller <typo3@brotkrueml.dev>
Tested-by: default avatarGarvin Hicking <gh@faktor-e.de>
Reviewed-by: default avatarGarvin Hicking <gh@faktor-e.de>
Tested-by: default avatarOliver Hader <oliver.hader@typo3.org>
Tested-by: default avatarChris Müller <typo3@brotkrueml.dev>
parent 91805a9a
Branches
Tags
No related merge requests found
......@@ -246,12 +246,18 @@ class Policy
return implode('; ', $policyParts);
}
/**
* Determines whether all sources are contained (in terms of instances and values, but without inference).
*/
public function containsDirective(Directive $directive, SourceCollection|SourceInterface ...$sources): bool
{
$sources = $this->asMergedSourceCollection(...$sources);
return (bool)$this->directives[$directive]?->contains(...$sources->sources);
}
/**
* Determines whether all sources are covered (in terms of CSP inference, considering wildcards and similar).
*/
public function coversDirective(Directive $directive, SourceCollection|SourceInterface ...$sources): bool
{
$sources = $this->asMergedSourceCollection(...$sources);
......@@ -298,7 +304,8 @@ class Policy
protected function changeDirectiveSources(Directive $directive, SourceCollection $sources): self
{
if ($sources->isEmpty() && !$directive->isStandAlone()) {
$isAlreadyEmpty = empty($this->directives[$directive]) || $this->directives[$directive]->isEmpty();
if ($isAlreadyEmpty && $sources->isEmpty() && !$directive->isStandAlone()) {
return $this;
}
$target = clone $this;
......
......@@ -27,6 +27,7 @@ use TYPO3\CMS\Core\Security\ContentSecurityPolicy\Mutation;
use TYPO3\CMS\Core\Security\ContentSecurityPolicy\MutationCollection;
use TYPO3\CMS\Core\Security\ContentSecurityPolicy\MutationMode;
use TYPO3\CMS\Core\Security\ContentSecurityPolicy\Policy;
use TYPO3\CMS\Core\Security\ContentSecurityPolicy\SourceInterface;
use TYPO3\CMS\Core\Security\ContentSecurityPolicy\SourceKeyword;
use TYPO3\CMS\Core\Security\ContentSecurityPolicy\SourceScheme;
use TYPO3\CMS\Core\Security\ContentSecurityPolicy\UriValue;
......@@ -170,13 +171,32 @@ final class PolicyTest extends FunctionalTestCase
self::assertSame("default-src 'self'; script-src 'unsafe-inline'", $policy->compile($this->nonce));
}
public static function directiveIsReducedDataProvider(): \Generator
{
yield 'one source remains' => [
'defaultSources' => [SourceKeyword::self, SourceKeyword::unsafeInline],
'reduceSources' => [SourceKeyword::self],
'expectation' => "script-src 'unsafe-inline'",
];
yield 'directive is purged' => [
'defaultSources' => [SourceKeyword::self],
'reduceSources' => [SourceKeyword::self],
'expectation' => '',
];
}
/**
* @param list<SourceInterface> $defaultSources
* @param list<SourceInterface> $reduceSources
*/
#[DataProvider('directiveIsReducedDataProvider')]
#[Test]
public function directiveIsReduced(): void
public function directiveIsReduced(array $defaultSources, array $reduceSources, string $expectation): void
{
$policy = (new Policy())
->set(Directive::ScriptSrc, SourceKeyword::self, SourceKeyword::unsafeInline)
->reduce(Directive::ScriptSrc, SourceKeyword::self);
self::assertSame("script-src 'unsafe-inline'", $policy->compile($this->nonce));
->set(Directive::ScriptSrc, ...$defaultSources)
->reduce(Directive::ScriptSrc, ...$reduceSources);
self::assertSame($expectation, $policy->compile($this->nonce));
}
#[Test]
......
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment