diff --git a/system/Security/Security.php b/system/Security/Security.php index 4ac0de3f8ff8..5ed56179b12e 100644 --- a/system/Security/Security.php +++ b/system/Security/Security.php @@ -27,6 +27,7 @@ use ErrorException; use JsonException; use SensitiveParameter; +use ValueError; /** * Class Security @@ -419,7 +420,7 @@ protected function derandomize(#[SensitiveParameter] string $token): string try { return bin2hex((string) hex2bin($value) ^ (string) hex2bin($key)); - } catch (ErrorException $e) { + } catch (ErrorException|ValueError $e) { // "hex2bin(): Hexadecimal input string must have an even length" throw new InvalidArgumentException($e->getMessage(), $e->getCode(), $e); } diff --git a/tests/system/Security/SecurityTest.php b/tests/system/Security/SecurityTest.php index 932dfc0df2c0..91ded2a743c5 100644 --- a/tests/system/Security/SecurityTest.php +++ b/tests/system/Security/SecurityTest.php @@ -15,6 +15,7 @@ use CodeIgniter\Config\Factories; use CodeIgniter\Config\Services; +use CodeIgniter\Exceptions\InvalidArgumentException; use CodeIgniter\HTTP\IncomingRequest; use CodeIgniter\HTTP\SiteURI; use CodeIgniter\HTTP\UserAgent; @@ -419,4 +420,15 @@ public static function provideGetPostedTokenReturnsNullForInvalidInputs(): itera yield 'invalid_form_data' => [self::createIncomingRequest()->setBody('csrf_test_name[]=invalid')]; } + + public function testDerandomizeThrowsInvalidArgumentExceptionOnInvalidHex(): void + { + $security = $this->createMockSecurity(); + $derandomize = self::getPrivateMethodInvoker($security, 'derandomize'); + + $this->expectException(InvalidArgumentException::class); + + // 'G' is not a valid hexadecimal character, which will trigger hex2bin's ValueError/Warning + $derandomize(str_repeat('G', 64)); + } }