From 6e98ce5dd2ce4cbbde2c5e14b61a40b24de1c5a6 Mon Sep 17 00:00:00 2001 From: neznaika0 Date: Sun, 14 Sep 2025 21:04:46 +0300 Subject: [PATCH 1/3] fix: Add missing translation (#9719) * fix: Add missing translation * docs: Update changelog * fix: Apply suggestions * fix: Restore and mark as deprecated `forNoHiddenValue()` * fix: Minor typo --- .../Honeypot/Exceptions/HoneypotException.php | 2 ++ system/I18n/Exceptions/I18nException.php | 2 +- system/Images/Handlers/ImageMagickHandler.php | 2 +- system/Language/en/Honeypot.php | 19 +++++++++++++++++++ system/Language/en/Router.php | 2 +- system/Router/Exceptions/RouterException.php | 2 +- user_guide_src/source/changelogs/v4.6.4.rst | 5 +++++ 7 files changed, 30 insertions(+), 4 deletions(-) create mode 100644 system/Language/en/Honeypot.php diff --git a/system/Honeypot/Exceptions/HoneypotException.php b/system/Honeypot/Exceptions/HoneypotException.php index 7ff493e4edf8..5185f6d3c843 100644 --- a/system/Honeypot/Exceptions/HoneypotException.php +++ b/system/Honeypot/Exceptions/HoneypotException.php @@ -41,6 +41,8 @@ public static function forNoNameField() * Thrown when the hidden value of config is false. * * @return static + * + * @deprecated 4.6.4 Never used. */ public static function forNoHiddenValue() { diff --git a/system/I18n/Exceptions/I18nException.php b/system/I18n/Exceptions/I18nException.php index 79c9e8326ad0..ec9dd3277e1e 100644 --- a/system/I18n/Exceptions/I18nException.php +++ b/system/I18n/Exceptions/I18nException.php @@ -72,7 +72,7 @@ public static function forInvalidOverDay(string $lastDay, string $day) */ public static function forInvalidHour(string $hour) { - return new static(lang('Time.invalidHour', [$hour])); + return new static(lang('Time.invalidHours', [$hour])); } /** diff --git a/system/Images/Handlers/ImageMagickHandler.php b/system/Images/Handlers/ImageMagickHandler.php index 233ea2d07149..bd2df0e49478 100644 --- a/system/Images/Handlers/ImageMagickHandler.php +++ b/system/Images/Handlers/ImageMagickHandler.php @@ -320,7 +320,7 @@ protected function supportedFormatCheck() switch ($this->image()->imageType) { case IMAGETYPE_WEBP: if (! in_array('WEBP', Imagick::queryFormats(), true)) { - throw ImageException::forInvalidImageCreate(lang('images.webpNotSupported')); + throw ImageException::forInvalidImageCreate(lang('Images.webpNotSupported')); } break; } diff --git a/system/Language/en/Honeypot.php b/system/Language/en/Honeypot.php new file mode 100644 index 000000000000..65676da56017 --- /dev/null +++ b/system/Language/en/Honeypot.php @@ -0,0 +1,19 @@ + + * + * For the full copyright and license information, please view + * the LICENSE file that was distributed with this source code. + */ + +// Honeypot language settings +return [ + 'noTemplate' => 'The HTML template for the Honeypot is not configured.', + 'noNameField' => 'The name of the Honeypot field is not set.', + 'theClientIsABot' => 'The Honeypot client may be a bot.', +]; diff --git a/system/Language/en/Router.php b/system/Language/en/Router.php index 7bb55860198b..a073d98d4ada 100644 --- a/system/Language/en/Router.php +++ b/system/Language/en/Router.php @@ -16,5 +16,5 @@ 'invalidParameter' => 'A parameter does not match the expected type.', 'missingDefaultRoute' => 'Unable to determine what should be displayed. A default route has not been specified in the routing file.', 'invalidDynamicController' => 'A dynamic controller is not allowed for security reasons. Route handler: "{0}"', - 'invalidControllerName' => 'The namespace delimiter is a backslash (\), not a slash (/). Route handler: "{0}"', + 'invalidControllerName' => 'The namespace delimiter is a backslash (\\), not a slash (/). Route handler: "{0}"', ]; diff --git a/system/Router/Exceptions/RouterException.php b/system/Router/Exceptions/RouterException.php index 378647289a72..7a65603d84b2 100644 --- a/system/Router/Exceptions/RouterException.php +++ b/system/Router/Exceptions/RouterException.php @@ -28,7 +28,7 @@ class RouterException extends FrameworkException implements ExceptionInterface */ public static function forInvalidParameterType() { - return new static(lang('Router.invalidParameterType')); + return new static(lang('Router.invalidParameter')); } /** diff --git a/user_guide_src/source/changelogs/v4.6.4.rst b/user_guide_src/source/changelogs/v4.6.4.rst index cc16d924fb03..ed9909d0face 100644 --- a/user_guide_src/source/changelogs/v4.6.4.rst +++ b/user_guide_src/source/changelogs/v4.6.4.rst @@ -18,6 +18,8 @@ BREAKING Message Changes *************** +- Added ``Honeypot.noTemplate``, ``Honeypot.noNameField``, ``Honeypot.theClientIsABot``. + ******* Changes ******* @@ -28,6 +30,9 @@ Changes Deprecations ************ +- **Exception:** + - The ``CodeIgniter\Honeypot\Exceptions\HoneypotException::forNoHiddenValue()`` method has been deprecated. Never used. + ********** Bugs Fixed ********** From a5567b841cb33c2f330bd3d0bf443337cf4fdc50 Mon Sep 17 00:00:00 2001 From: Mark Unwin Date: Tue, 16 Sep 2025 10:21:46 +1000 Subject: [PATCH 2/3] feat: Add script-src-elem option to CSP options. Signed-off-by: Mark Unwin --- app/Config/ContentSecurityPolicy.php | 7 +++++++ system/HTTP/ContentSecurityPolicy.php | 25 +++++++++++++++++++++++++ 2 files changed, 32 insertions(+) diff --git a/app/Config/ContentSecurityPolicy.php b/app/Config/ContentSecurityPolicy.php index 2ac41a70dadb..f807b29fcfbb 100644 --- a/app/Config/ContentSecurityPolicy.php +++ b/app/Config/ContentSecurityPolicy.php @@ -56,6 +56,13 @@ class ContentSecurityPolicy extends BaseConfig */ public $scriptSrc = 'self'; + /** + * Lists allowed scripts' URLs. + * + * @var list|string + */ + public $scriptSrcElem = 'self'; + /** * Lists allowed stylesheets' URLs. * diff --git a/system/HTTP/ContentSecurityPolicy.php b/system/HTTP/ContentSecurityPolicy.php index a6a2b26a71fc..9936d7ed39e1 100644 --- a/system/HTTP/ContentSecurityPolicy.php +++ b/system/HTTP/ContentSecurityPolicy.php @@ -47,6 +47,7 @@ class ContentSecurityPolicy 'object-src' => 'objectSrc', 'plugin-types' => 'pluginTypes', 'script-src' => 'scriptSrc', + 'script-src-elem' => 'scriptSrcElem', 'style-src' => 'styleSrc', 'manifest-src' => 'manifestSrc', 'sandbox' => 'sandbox', @@ -144,6 +145,13 @@ class ContentSecurityPolicy */ protected $scriptSrc = []; + /** + * Used for security enforcement + * + * @var array|string + */ + protected $scriptSrcElem = []; + /** * Used for security enforcement * @@ -641,6 +649,23 @@ public function addScriptSrc($uri, ?bool $explicitReporting = null) return $this; } + /** + * Adds a new valid endpoint for javascript file sources. Can be either + * a URI class or a simple string. + * + * @see https://www.w3.org/TR/CSP/#directive-script-src-elem + * + * @param array|string $uri + * + * @return $this + */ + public function addScriptSrcElem($uri, ?bool $explicitReporting = null) + { + $this->addOption($uri, 'scriptSrcElem', $explicitReporting ?? $this->reportOnly); + + return $this; + } + /** * Adds a new valid endpoint for CSS file sources. Can be either * a URI class or a simple string. From 3fb4927d4dde6cdbd6bc229390c0773a7341cfaa Mon Sep 17 00:00:00 2001 From: Mark Unwin Date: Tue, 16 Sep 2025 10:34:26 +1000 Subject: [PATCH 3/3] fix: Add missing unit test for script-src-elem. Signed-off-by: Mark Unwin --- tests/system/HTTP/ContentSecurityPolicyTest.php | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/tests/system/HTTP/ContentSecurityPolicyTest.php b/tests/system/HTTP/ContentSecurityPolicyTest.php index 06dde464a4a4..4346076bfbd2 100644 --- a/tests/system/HTTP/ContentSecurityPolicyTest.php +++ b/tests/system/HTTP/ContentSecurityPolicyTest.php @@ -302,6 +302,21 @@ public function testScriptSrc(): void $this->assertStringContainsString("script-src 'self' cdn.cloudy.com;", (string) $result); } + #[PreserveGlobalState(false)] + #[RunInSeparateProcess] + public function testScriptSrcElem(): void + { + $this->prepare(); + $this->csp->addScriptSrcElem('cdn.cloudy.com'); + $this->csp->addScriptSrcElem('them.com', true); + $result = $this->work(); + + $result = $this->getHeaderEmitted('Content-Security-Policy-Report-Only'); + $this->assertStringContainsString('script-src-elem them.com;', (string) $result); + $result = $this->getHeaderEmitted('Content-Security-Policy'); + $this->assertStringContainsString("script-src-elem 'self' cdn.cloudy.com;", (string) $result); + } + #[PreserveGlobalState(false)] #[RunInSeparateProcess] public function testStyleSrc(): void