Skip to content

Commit dc35649

Browse files
RobertMenicolas-grekas
authored andcommitted
[Security] Fix possible session fixation when only the *token* changes
1 parent b421063 commit dc35649

File tree

2 files changed

+22
-1
lines changed

2 files changed

+22
-1
lines changed

src/Symfony/Component/Security/Http/EventListener/SessionStrategyListener.php

+1-1
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@ public function onSuccessfulLogin(LoginSuccessEvent $event): void
4848
$user = method_exists($token, 'getUserIdentifier') ? $token->getUserIdentifier() : $token->getUsername();
4949
$previousUser = method_exists($previousToken, 'getUserIdentifier') ? $previousToken->getUserIdentifier() : $previousToken->getUsername();
5050

51-
if ('' !== ($user ?? '') && $user === $previousUser) {
51+
if ('' !== ($user ?? '') && $user === $previousUser && \get_class($token) === \get_class($previousToken)) {
5252
return;
5353
}
5454
}

src/Symfony/Component/Security/Http/Tests/EventListener/SessionStrategyListenerTest.php

+21
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
use Symfony\Component\HttpFoundation\Request;
1616
use Symfony\Component\HttpFoundation\Session\SessionInterface;
1717
use Symfony\Component\Security\Core\Authentication\Token\NullToken;
18+
use Symfony\Component\Security\Core\Authentication\Token\UsernamePasswordToken;
1819
use Symfony\Component\Security\Core\User\InMemoryUser;
1920
use Symfony\Component\Security\Http\Authenticator\AuthenticatorInterface;
2021
use Symfony\Component\Security\Http\Authenticator\Passport\Badge\UserBadge;
@@ -81,6 +82,26 @@ public function testRequestWithSamePreviousUser()
8182
$this->listener->onSuccessfulLogin($event);
8283
}
8384

85+
public function testRequestWithSamePreviousUserButDifferentTokenType()
86+
{
87+
$this->configurePreviousSession();
88+
89+
$token = $this->createMock(NullToken::class);
90+
$token->expects($this->once())
91+
->method('getUserIdentifier')
92+
->willReturn('test');
93+
$previousToken = $this->createMock(UsernamePasswordToken::class);
94+
$previousToken->expects($this->once())
95+
->method('getUserIdentifier')
96+
->willReturn('test');
97+
98+
$this->sessionAuthenticationStrategy->expects($this->once())->method('onAuthentication')->with($this->request, $token);
99+
100+
$event = new LoginSuccessEvent($this->createMock(AuthenticatorInterface::class), new SelfValidatingPassport(new UserBadge('test', function () {})), $token, $this->request, null, 'main_firewall', $previousToken);
101+
102+
$this->listener->onSuccessfulLogin($event);
103+
}
104+
84105
private function createEvent($firewallName)
85106
{
86107
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);

0 commit comments

Comments
 (0)