Skip to content

Commit 0fe15ad

Browse files
authored
fix: add nonce to script-src-elem and style-src-elem when configured (#9999)
1 parent 93595cf commit 0fe15ad

File tree

3 files changed

+51
-0
lines changed

3 files changed

+51
-0
lines changed

system/HTTP/ContentSecurityPolicy.php

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -400,6 +400,10 @@ public function getStyleNonce(): string
400400
if ($this->styleNonce === null) {
401401
$this->styleNonce = base64_encode(random_bytes(12));
402402
$this->addStyleSrc('nonce-' . $this->styleNonce);
403+
404+
if ($this->styleSrcElem !== []) {
405+
$this->addStyleSrcElem('nonce-' . $this->styleNonce);
406+
}
403407
}
404408

405409
return $this->styleNonce;
@@ -413,6 +417,10 @@ public function getScriptNonce(): string
413417
if ($this->scriptNonce === null) {
414418
$this->scriptNonce = base64_encode(random_bytes(12));
415419
$this->addScriptSrc('nonce-' . $this->scriptNonce);
420+
421+
if ($this->scriptSrcElem !== []) {
422+
$this->addScriptSrcElem('nonce-' . $this->scriptNonce);
423+
}
416424
}
417425

418426
return $this->scriptNonce;

tests/system/HTTP/ContentSecurityPolicyTest.php

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -900,6 +900,48 @@ public function testGetStyleNonce(): void
900900
);
901901
}
902902

903+
public function testGetScriptNonceAddsNonceToScriptSrcElemWhenConfigured(): void
904+
{
905+
$this->csp->clearDirective('script-src-elem');
906+
$this->csp->addScriptSrcElem('cdn.example.com');
907+
$nonce = $this->csp->getScriptNonce();
908+
$this->csp->finalize($this->response);
909+
910+
$directives = $this->getCspDirectives($this->response->getHeaderLine('Content-Security-Policy'));
911+
$this->assertContains("script-src-elem cdn.example.com 'nonce-{$nonce}'", $directives);
912+
}
913+
914+
public function testGetScriptNonceDoesNotAddNonceToScriptSrcElemWhenCleared(): void
915+
{
916+
$this->csp->clearDirective('script-src-elem');
917+
$this->csp->getScriptNonce();
918+
$this->csp->finalize($this->response);
919+
920+
$header = $this->response->getHeaderLine('Content-Security-Policy');
921+
$this->assertStringNotContainsString('script-src-elem', $header);
922+
}
923+
924+
public function testGetStyleNonceAddsNonceToStyleSrcElemWhenConfigured(): void
925+
{
926+
$this->csp->clearDirective('style-src-elem');
927+
$this->csp->addStyleSrcElem('cdn.example.com');
928+
$nonce = $this->csp->getStyleNonce();
929+
$this->csp->finalize($this->response);
930+
931+
$directives = $this->getCspDirectives($this->response->getHeaderLine('Content-Security-Policy'));
932+
$this->assertContains("style-src-elem cdn.example.com 'nonce-{$nonce}'", $directives);
933+
}
934+
935+
public function testGetStyleNonceDoesNotAddNonceToStyleSrcElemWhenCleared(): void
936+
{
937+
$this->csp->clearDirective('style-src-elem');
938+
$this->csp->getStyleNonce();
939+
$this->csp->finalize($this->response);
940+
941+
$header = $this->response->getHeaderLine('Content-Security-Policy');
942+
$this->assertStringNotContainsString('style-src-elem', $header);
943+
}
944+
903945
#[PreserveGlobalState(false)]
904946
#[RunInSeparateProcess]
905947
public function testHeaderScriptNonceEmittedOnceGetScriptNonceCalled(): void

user_guide_src/source/changelogs/v4.7.1.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,7 @@ Bugs Fixed
4949

5050
- **ContentSecurityPolicy:** Fixed a bug where custom CSP tags were not removed from generated HTML when CSP was disabled. The method now ensures that all custom CSP tags are removed from the generated HTML.
5151
- **ContentSecurityPolicy:** Fixed a bug where ``generateNonces()`` produces corrupted JSON responses by replacing CSP nonce placeholders with unescaped double quotes. The method now automatically JSON-escapes nonce attributes when the response Content-Type is JSON.
52+
- **ContentSecurityPolicy:** Fixed a bug where nonces generated by ``getScriptNonce()`` and ``getStyleNonce()`` were not added to the ``script-src-elem`` and ``style-src-elem`` directives, causing nonces to be silently ignored by browsers when those directives were present.
5253
- **Database:** Fixed a bug where ``BaseConnection::callFunction()`` could double-prefix already-prefixed function names.
5354
- **Database:** Fixed a bug where ``BasePreparedQuery::prepare()`` could mis-handle SQL containing colon syntax by over-broad named-placeholder replacement. It now preserves PostgreSQL cast syntax like ``::timestamp``.
5455
- **Model:** Fixed a bug where ``BaseModel::updateBatch()`` threw an exception when ``updateOnlyChanged`` was ``true`` and the index field value did not change.

0 commit comments

Comments
 (0)