VYPR
Moderate severityNVD Advisory· Published Nov 10, 2023· Updated Sep 3, 2024

Symfony possible session fixation vulnerability

CVE-2023-46733

Description

Symfony is a PHP framework for web and console applications and a set of reusable PHP components. Starting in versions 5.4.21 and 6.2.7 and prior to versions 5.4.31 and 6.3.8, SessionStrategyListener does not migrate the session after every successful login. It does so only in case the logged in user changes by means of checking the user identifier. In some use cases, the user identifier doesn't change between the verification phase and the successful login, while the token itself changes from one type (partially-authenticated) to another (fully-authenticated). When this happens, the session id should be regenerated to prevent possible session fixations, which is not the case at the moment. As of versions 5.4.31 and 6.3.8, Symfony now checks the type of the token in addition to the user identifier before deciding whether the session id should be regenerated.

Affected packages

Versions sourced from the GitHub Security Advisory.

PackageAffected versionsPatched versions
symfony/security-httpPackagist
>= 5.4.21, < 5.4.315.4.31
symfony/security-httpPackagist
>= 6.2.7, < 6.3.86.3.8
symfony/symfonyPackagist
>= 5.4.21, < 5.4.315.4.31
symfony/symfonyPackagist
>= 6.2.7, < 6.3.86.3.8

Affected products

1

Patches

2
7467bd7e3f88

security #cve-2023-46733 [Security] Fix possible session fixation when only the *token* changes (RobertMe)

https://github.com/symfony/symfonyNicolas GrekasNov 9, 2023via ghsa
2 files changed · +22 1
  • src/Symfony/Component/Security/Http/EventListener/SessionStrategyListener.php+1 1 modified
    @@ -48,7 +48,7 @@ public function onSuccessfulLogin(LoginSuccessEvent $event): void
                 $user = method_exists($token, 'getUserIdentifier') ? $token->getUserIdentifier() : $token->getUsername();
                 $previousUser = method_exists($previousToken, 'getUserIdentifier') ? $previousToken->getUserIdentifier() : $previousToken->getUsername();
     
    -            if ('' !== ($user ?? '') && $user === $previousUser) {
    +            if ('' !== ($user ?? '') && $user === $previousUser && \get_class($token) === \get_class($previousToken)) {
                     return;
                 }
             }
    
  • src/Symfony/Component/Security/Http/Tests/EventListener/SessionStrategyListenerTest.php+21 0 modified
    @@ -15,6 +15,7 @@
     use Symfony\Component\HttpFoundation\Request;
     use Symfony\Component\HttpFoundation\Session\SessionInterface;
     use Symfony\Component\Security\Core\Authentication\Token\NullToken;
    +use Symfony\Component\Security\Core\Authentication\Token\UsernamePasswordToken;
     use Symfony\Component\Security\Core\User\InMemoryUser;
     use Symfony\Component\Security\Http\Authenticator\AuthenticatorInterface;
     use Symfony\Component\Security\Http\Authenticator\Passport\Badge\UserBadge;
    @@ -81,6 +82,26 @@ public function testRequestWithSamePreviousUser()
             $this->listener->onSuccessfulLogin($event);
         }
     
    +    public function testRequestWithSamePreviousUserButDifferentTokenType()
    +    {
    +        $this->configurePreviousSession();
    +
    +        $token = $this->createMock(NullToken::class);
    +        $token->expects($this->once())
    +            ->method('getUserIdentifier')
    +            ->willReturn('test');
    +        $previousToken = $this->createMock(UsernamePasswordToken::class);
    +        $previousToken->expects($this->once())
    +            ->method('getUserIdentifier')
    +            ->willReturn('test');
    +
    +        $this->sessionAuthenticationStrategy->expects($this->once())->method('onAuthentication')->with($this->request, $token);
    +
    +        $event = new LoginSuccessEvent($this->createMock(AuthenticatorInterface::class), new SelfValidatingPassport(new UserBadge('test', function () {})), $token, $this->request, null, 'main_firewall', $previousToken);
    +
    +        $this->listener->onSuccessfulLogin($event);
    +    }
    +
         private function createEvent($firewallName)
         {
             return new LoginSuccessEvent($this->createMock(AuthenticatorInterface::class), new SelfValidatingPassport(new UserBadge('test', function ($username) { return new InMemoryUser($username, null); })), $this->token, $this->request, null, $firewallName);
    
dc356499d5ce

[Security] Fix possible session fixation when only the *token* changes

https://github.com/symfony/symfonyRobertNov 3, 2023via ghsa
2 files changed · +22 1
  • src/Symfony/Component/Security/Http/EventListener/SessionStrategyListener.php+1 1 modified
    @@ -48,7 +48,7 @@ public function onSuccessfulLogin(LoginSuccessEvent $event): void
                 $user = method_exists($token, 'getUserIdentifier') ? $token->getUserIdentifier() : $token->getUsername();
                 $previousUser = method_exists($previousToken, 'getUserIdentifier') ? $previousToken->getUserIdentifier() : $previousToken->getUsername();
     
    -            if ('' !== ($user ?? '') && $user === $previousUser) {
    +            if ('' !== ($user ?? '') && $user === $previousUser && \get_class($token) === \get_class($previousToken)) {
                     return;
                 }
             }
    
  • src/Symfony/Component/Security/Http/Tests/EventListener/SessionStrategyListenerTest.php+21 0 modified
    @@ -15,6 +15,7 @@
     use Symfony\Component\HttpFoundation\Request;
     use Symfony\Component\HttpFoundation\Session\SessionInterface;
     use Symfony\Component\Security\Core\Authentication\Token\NullToken;
    +use Symfony\Component\Security\Core\Authentication\Token\UsernamePasswordToken;
     use Symfony\Component\Security\Core\User\InMemoryUser;
     use Symfony\Component\Security\Http\Authenticator\AuthenticatorInterface;
     use Symfony\Component\Security\Http\Authenticator\Passport\Badge\UserBadge;
    @@ -81,6 +82,26 @@ public function testRequestWithSamePreviousUser()
             $this->listener->onSuccessfulLogin($event);
         }
     
    +    public function testRequestWithSamePreviousUserButDifferentTokenType()
    +    {
    +        $this->configurePreviousSession();
    +
    +        $token = $this->createMock(NullToken::class);
    +        $token->expects($this->once())
    +            ->method('getUserIdentifier')
    +            ->willReturn('test');
    +        $previousToken = $this->createMock(UsernamePasswordToken::class);
    +        $previousToken->expects($this->once())
    +            ->method('getUserIdentifier')
    +            ->willReturn('test');
    +
    +        $this->sessionAuthenticationStrategy->expects($this->once())->method('onAuthentication')->with($this->request, $token);
    +
    +        $event = new LoginSuccessEvent($this->createMock(AuthenticatorInterface::class), new SelfValidatingPassport(new UserBadge('test', function () {})), $token, $this->request, null, 'main_firewall', $previousToken);
    +
    +        $this->listener->onSuccessfulLogin($event);
    +    }
    +
         private function createEvent($firewallName)
         {
             return new LoginSuccessEvent($this->createMock(AuthenticatorInterface::class), new SelfValidatingPassport(new UserBadge('test', function ($username) { return new InMemoryUser($username, null); })), $this->token, $this->request, null, $firewallName);
    

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

News mentions

0

No linked articles in our index yet.