High severity7.5NVD Advisory· Published Nov 13, 2024· Updated Apr 15, 2026
CVE-2024-51996
CVE-2024-51996
Description
Symphony process is a module for the Symphony PHP framework which executes commands in sub-processes. When consuming a persisted remember-me cookie, Symfony does not check if the username persisted in the database matches the username attached with the cookie, leading to authentication bypass. This vulnerability is fixed in 5.4.47, 6.4.15, and 7.1.8.
Affected packages
Versions sourced from the GitHub Security Advisory.
| Package | Affected versions | Patched versions |
|---|---|---|
symfony/security-httpPackagist | >= 5.3.0, < 5.4.47 | 5.4.47 |
symfony/security-httpPackagist | >= 6.0.0-BETA1, < 6.4.15 | 6.4.15 |
symfony/security-httpPackagist | >= 7.0.0-BETA1, < 7.1.8 | 7.1.8 |
Patches
4d869cc180cf3cfb00ec539f6fa8dfde81afc81354d392c5f[security-http] Check owner of persisted remember-me cookie
2 files changed · +48 −5
src/Symfony/Component/Security/Http/RememberMe/PersistentRememberMeHandler.php+16 −3 modified@@ -66,9 +66,16 @@ public function consumeRememberMeCookie(RememberMeDetails $rememberMeDetails): U throw new AuthenticationException('The cookie is incorrectly formatted.'); } - [$series, $tokenValue] = explode(':', $rememberMeDetails->getValue()); + [$series, $tokenValue] = explode(':', $rememberMeDetails->getValue(), 2); $persistentToken = $this->tokenProvider->loadTokenBySeries($series); + if ($persistentToken->getUserIdentifier() !== $rememberMeDetails->getUserIdentifier() || $persistentToken->getClass() !== $rememberMeDetails->getUserFqcn()) { + throw new AuthenticationException('The cookie\'s hash is invalid.'); + } + + // content of $rememberMeDetails is not trustable. this prevents use of this class + unset($rememberMeDetails); + if ($this->tokenVerifier) { $isTokenValid = $this->tokenVerifier->verifyToken($persistentToken, $tokenValue); } else { @@ -78,11 +85,17 @@ public function consumeRememberMeCookie(RememberMeDetails $rememberMeDetails): U throw new CookieTheftException('This token was already used. The account is possibly compromised.'); } - if ($persistentToken->getLastUsed()->getTimestamp() + $this->options['lifetime'] < time()) { + $expires = $persistentToken->getLastUsed()->getTimestamp() + $this->options['lifetime']; + if ($expires < time()) { throw new AuthenticationException('The cookie has expired.'); } - return parent::consumeRememberMeCookie($rememberMeDetails->withValue($persistentToken->getLastUsed()->getTimestamp().':'.$rememberMeDetails->getValue().':'.$persistentToken->getClass())); + return parent::consumeRememberMeCookie(new RememberMeDetails( + $persistentToken->getClass(), + $persistentToken->getUserIdentifier(), + $expires, + $persistentToken->getLastUsed()->getTimestamp().':'.$series.':'.$tokenValue.':'.$persistentToken->getClass() + )); } public function processRememberMe(RememberMeDetails $rememberMeDetails, UserInterface $user): void
src/Symfony/Component/Security/Http/Tests/RememberMe/PersistentRememberMeHandlerTest.php+32 −2 modified@@ -80,7 +80,7 @@ public function testConsumeRememberMeCookieValid() $this->tokenProvider->expects($this->any()) ->method('loadTokenBySeries') ->with('series1') - ->willReturn(new PersistentToken(InMemoryUser::class, 'wouter', 'series1', 'tokenvalue', new \DateTime('-10 min'))) + ->willReturn(new PersistentToken(InMemoryUser::class, 'wouter', 'series1', 'tokenvalue', $lastUsed = new \DateTime('-10 min'))) ; $this->tokenProvider->expects($this->once())->method('updateToken')->with('series1'); @@ -98,11 +98,41 @@ public function testConsumeRememberMeCookieValid() $this->assertSame($rememberParts[0], $cookieParts[0]); // class $this->assertSame($rememberParts[1], $cookieParts[1]); // identifier - $this->assertSame($rememberParts[2], $cookieParts[2]); // expire + $this->assertEqualsWithDelta($lastUsed->getTimestamp() + 31536000, (int) $cookieParts[2], 2); // expire $this->assertNotSame($rememberParts[3], $cookieParts[3]); // value $this->assertSame(explode(':', $rememberParts[3])[0], explode(':', $cookieParts[3])[0]); // series } + public function testConsumeRememberMeCookieInvalidOwner() + { + $this->tokenProvider->expects($this->any()) + ->method('loadTokenBySeries') + ->with('series1') + ->willReturn(new PersistentToken(InMemoryUser::class, 'wouter', 'series1', 'tokenvalue', new \DateTime('-10 min'))) + ; + + $rememberMeDetails = new RememberMeDetails(InMemoryUser::class, 'jeremy', 360, 'series1:tokenvalue'); + + $this->expectException(AuthenticationException::class); + $this->expectExceptionMessage('The cookie\'s hash is invalid.'); + $this->handler->consumeRememberMeCookie($rememberMeDetails); + } + + public function testConsumeRememberMeCookieInvalidValue() + { + $this->tokenProvider->expects($this->any()) + ->method('loadTokenBySeries') + ->with('series1') + ->willReturn(new PersistentToken(InMemoryUser::class, 'wouter', 'series1', 'tokenvalue', new \DateTime('-10 min'))) + ; + + $rememberMeDetails = new RememberMeDetails(InMemoryUser::class, 'wouter', 360, 'series1:tokenvalue:somethingelse'); + + $this->expectException(AuthenticationException::class); + $this->expectExceptionMessage('This token was already used. The account is possibly compromised.'); + $this->handler->consumeRememberMeCookie($rememberMeDetails); + } + public function testConsumeRememberMeCookieValidByValidatorWithoutUpdate() { $verifier = $this->createMock(TokenVerifierInterface::class);
Vulnerability mechanics
Generated by null/stub on May 9, 2026. Inputs: CWE entries + fix-commit diffs from this CVE's patches. Citations validated against bundle.
References
7- github.com/advisories/GHSA-cg23-qf8f-62rrghsaADVISORY
- nvd.nist.gov/vuln/detail/CVE-2024-51996ghsaADVISORY
- github.com/FriendsOfPHP/security-advisories/blob/master/symfony/security-http/CVE-2024-51996.yamlghsaWEB
- github.com/FriendsOfPHP/security-advisories/blob/master/symfony/symfony/CVE-2024-51996.yamlghsaWEB
- github.com/symfony/symfony/commit/81354d392c5f0b7a52bcbd729d6f82501e94135anvdWEB
- github.com/symfony/symfony/security/advisories/GHSA-cg23-qf8f-62rrnvdWEB
- symfony.com/cve-2024-51996ghsaWEB
News mentions
0No linked articles in our index yet.