diff --git a/src/Symfony/Component/Security/Csrf/CsrfTokenManager.php b/src/Symfony/Component/Security/Csrf/CsrfTokenManager.php index 3e7454e793d28..14c05592d3241 100644 --- a/src/Symfony/Component/Security/Csrf/CsrfTokenManager.php +++ b/src/Symfony/Component/Security/Csrf/CsrfTokenManager.php @@ -134,6 +134,9 @@ private function derandomize(string $value): string return $value; } $key = base64_decode(strtr($parts[1], '-_', '+/')); + if ('' === $key || false === $key) { + return $value; + } $value = base64_decode(strtr($parts[2], '-_', '+/')); return $this->xor($value, $key); diff --git a/src/Symfony/Component/Security/Csrf/Tests/CsrfTokenManagerTest.php b/src/Symfony/Component/Security/Csrf/Tests/CsrfTokenManagerTest.php index d654bbf195fa4..bd911987f1f2d 100644 --- a/src/Symfony/Component/Security/Csrf/Tests/CsrfTokenManagerTest.php +++ b/src/Symfony/Component/Security/Csrf/Tests/CsrfTokenManagerTest.php @@ -193,6 +193,26 @@ public function testNonExistingTokenIsNotValid($namespace, $manager, $storage) $this->assertFalse($manager->isTokenValid(new CsrfToken('token_id', 'FOOBAR'))); } + public function testTokenShouldNotTriggerDivisionByZero() + { + [$generator, $storage] = $this->getGeneratorAndStorage(); + $manager = new CsrfTokenManager($generator, $storage); + + // Scenario: the token that was returned is abc.def.ghi, and gets modified in the browser to abc..ghi + + $storage->expects($this->once()) + ->method('hasToken') + ->with('https-token_id') + ->willReturn(true); + + $storage->expects($this->once()) + ->method('getToken') + ->with('https-token_id') + ->willReturn('def'); + + $this->assertFalse($manager->isTokenValid(new CsrfToken('token_id', 'abc..ghi'))); + } + /** * @dataProvider getManagerGeneratorAndStorage */