From 0222ed3a3284ce65753a24b812ee16205fa34754 Mon Sep 17 00:00:00 2001 From: Romaric Drigon Date: Tue, 1 Dec 2020 10:37:05 +0100 Subject: [PATCH] [Security] fix #39262, more defensive PasswordMigratingListener --- .../EventListener/PasswordMigratingListener.php | 5 +++++ .../PasswordMigratingListenerTest.php | 15 +++++++++++++++ 2 files changed, 20 insertions(+) diff --git a/src/Symfony/Component/Security/Http/EventListener/PasswordMigratingListener.php b/src/Symfony/Component/Security/Http/EventListener/PasswordMigratingListener.php index d667b5826eaca..81d4c04838619 100644 --- a/src/Symfony/Component/Security/Http/EventListener/PasswordMigratingListener.php +++ b/src/Symfony/Component/Security/Http/EventListener/PasswordMigratingListener.php @@ -56,7 +56,12 @@ public function onLoginSuccess(LoginSuccessEvent $event): void } $passwordUpgrader = $badge->getPasswordUpgrader(); + if (null === $passwordUpgrader) { + if (!$passport->hasBadge(UserBadge::class)) { + return; + } + /** @var UserBadge $userBadge */ $userBadge = $passport->getBadge(UserBadge::class); $userLoader = $userBadge->getUserLoader(); diff --git a/src/Symfony/Component/Security/Http/Tests/EventListener/PasswordMigratingListenerTest.php b/src/Symfony/Component/Security/Http/Tests/EventListener/PasswordMigratingListenerTest.php index 42607ca853328..39a62e0f69d68 100644 --- a/src/Symfony/Component/Security/Http/Tests/EventListener/PasswordMigratingListenerTest.php +++ b/src/Symfony/Component/Security/Http/Tests/EventListener/PasswordMigratingListenerTest.php @@ -24,6 +24,7 @@ use Symfony\Component\Security\Http\Authenticator\Passport\Badge\UserBadge; use Symfony\Component\Security\Http\Authenticator\Passport\PassportInterface; use Symfony\Component\Security\Http\Authenticator\Passport\SelfValidatingPassport; +use Symfony\Component\Security\Http\Authenticator\Passport\UserPassportInterface; use Symfony\Component\Security\Http\Event\LoginSuccessEvent; use Symfony\Component\Security\Http\EventListener\PasswordMigratingListener; @@ -67,6 +68,20 @@ public function provideUnsupportedEvents() yield [$this->createEvent($this->createMock(PassportInterface::class))]; } + public function testUnsupportedPassport() + { + // A custom Passport, without an UserBadge + $passport = $this->createMock(UserPassportInterface::class); + $passport->method('getUser')->willReturn($this->user); + $passport->method('hasBadge')->withConsecutive([PasswordUpgradeBadge::class], [UserBadge::class])->willReturnOnConsecutiveCalls(true, false); + $passport->expects($this->once())->method('getBadge')->with(PasswordUpgradeBadge::class)->willReturn(new PasswordUpgradeBadge('pa$$word')); + // We should never "getBadge" for "UserBadge::class" + + $event = $this->createEvent($passport); + + $this->listener->onLoginSuccess($event); + } + public function testUpgradeWithUpgrader() { $passwordUpgrader = $this->createPasswordUpgrader();