Package: release.debian.org Severity: normal User: release.debian....@packages.debian.org Usertags: unblock X-Debbugs-Cc: t...@security.debian.org
Please unblock package symfony I’ve uploaded a targeted fix for a user enumeration [CVE-2021-21424]. Since symfony is a key package, it won’t migrate on its own despite the autopkgtests. I also fixed two typos in the packages description. [ Checklist ] [x] all changes are documented in the d/changelog [x] I reviewed all changes and I approve them [x] attach debdiff against the package in testing Regards unblock symfony/4.4.19+dfsg-2
diff --git a/debian/changelog b/debian/changelog index 342ccafaef..db978be8b7 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,3 +1,10 @@ +symfony (4.4.19+dfsg-2) unstable; urgency=medium + + * Prevent user enumeration via response content [CVE-2021-21424] + * typo fix: var-exporter and phpunit-bridge description + + -- David Prévot <taf...@debian.org> Thu, 13 May 2021 05:33:42 -0400 + symfony (4.4.19+dfsg-1) unstable; urgency=medium [ Fabien Potencier ] diff --git a/debian/control b/debian/control index c5df2fc3cc..d19d505d56 100644 --- a/debian/control +++ b/debian/control @@ -765,7 +765,7 @@ Breaks: ${phpcomposer:Debian-conflict}, ${phpcomposer:Debian-replace} Provides: ${phpcomposer:Debian-provide} Homepage: https://symfony.com/doc/4.4/components/var_exporter.html Description: export serializable PHP data structure to plain PHP code - The Symfony VarExporter allows one to exporte any serializable PHP data + The Symfony VarExporter allows one to export any serializable PHP data structure to plain PHP code. . Symfony is a PHP framework, a set of tools and a development methodology. @@ -864,7 +864,7 @@ Breaks: ${phpcomposer:Debian-replace} Provides: ${phpcomposer:Debian-provide} Homepage: https://symfony.com/doc/4.4/components/phpunit_bridge.html Description: integration for PHPUnit with Symfony Components - The Symfony PHPUnit Bridge utilities for PHPUnit, especially user + The Symfony PHPUnit Bridge provides utilities for PHPUnit, especially user deprecation notices management. . PHPUnit is a unit testing suite for the PHP language, modelled on the diff --git a/debian/patches/Merge-branch-3.4-into-4.4.patch b/debian/patches/Merge-branch-3.4-into-4.4.patch new file mode 100644 index 0000000000..02d7a16017 --- /dev/null +++ b/debian/patches/Merge-branch-3.4-into-4.4.patch @@ -0,0 +1,210 @@ +From: Nicolas Grekas <nicolas.gre...@gmail.com> +Date: Wed, 12 May 2021 14:42:28 +0200 +Subject: Merge branch '3.4' into 4.4 + +* 3.4: + [Security][Guard] Prevent user enumeration via response content + +Origin: upstream, https://github.com/symfony/symfony/commit/f012eee6c6034a94566dff596fe4e16dfc5d9c1f https://github.com/symfony/symfony/commit/d5c0fbac859374754ee14b524a1e157534ee07de +Bug-Debian-Security: https://security-tracker.debian.org/tracker/CVE-2021-21424 +--- + .../SecurityBundle/Resources/config/guard.xml | 3 +- + .../Provider/UserAuthenticationProvider.php | 3 +- + .../Provider/UserAuthenticationProviderTest.php | 6 +-- + .../Guard/Firewall/GuardAuthenticationListener.php | 13 +++++- + .../Firewall/GuardAuthenticationListenerTest.php | 51 ++++++++++++++++++++++ + 5 files changed, 70 insertions(+), 6 deletions(-) + +diff --git a/src/Symfony/Bundle/SecurityBundle/Resources/config/guard.xml b/src/Symfony/Bundle/SecurityBundle/Resources/config/guard.xml +index 7b17aff..2fae143 100644 +--- a/src/Symfony/Bundle/SecurityBundle/Resources/config/guard.xml ++++ b/src/Symfony/Bundle/SecurityBundle/Resources/config/guard.xml +@@ -17,7 +17,7 @@ + <argument type="service" id="security.authentication.session_strategy" /> + </call> + </service> +- ++ + <service id="Symfony\Component\Security\Guard\GuardAuthenticatorHandler" alias="security.authentication.guard_handler" /> + + <!-- See GuardAuthenticationFactory --> +@@ -42,6 +42,7 @@ + <argument /> <!-- Provider-shared Key --> + <argument /> <!-- Authenticator --> + <argument type="service" id="logger" on-invalid="null" /> ++ <argument>%security.authentication.hide_user_not_found%</argument> + </service> + </services> + </container> +diff --git a/src/Symfony/Component/Security/Core/Authentication/Provider/UserAuthenticationProvider.php b/src/Symfony/Component/Security/Core/Authentication/Provider/UserAuthenticationProvider.php +index 9912259..86ef627 100644 +--- a/src/Symfony/Component/Security/Core/Authentication/Provider/UserAuthenticationProvider.php ++++ b/src/Symfony/Component/Security/Core/Authentication/Provider/UserAuthenticationProvider.php +@@ -14,6 +14,7 @@ namespace Symfony\Component\Security\Core\Authentication\Provider; + use Symfony\Component\Security\Core\Authentication\Token\SwitchUserToken; + use Symfony\Component\Security\Core\Authentication\Token\TokenInterface; + use Symfony\Component\Security\Core\Authentication\Token\UsernamePasswordToken; ++use Symfony\Component\Security\Core\Exception\AccountStatusException; + use Symfony\Component\Security\Core\Exception\AuthenticationException; + use Symfony\Component\Security\Core\Exception\AuthenticationServiceException; + use Symfony\Component\Security\Core\Exception\BadCredentialsException; +@@ -80,7 +81,7 @@ abstract class UserAuthenticationProvider implements AuthenticationProviderInter + $this->userChecker->checkPreAuth($user); + $this->checkAuthentication($user, $token); + $this->userChecker->checkPostAuth($user); +- } catch (BadCredentialsException $e) { ++ } catch (AccountStatusException $e) { + if ($this->hideUserNotFoundExceptions) { + throw new BadCredentialsException('Bad credentials.', 0, $e); + } +diff --git a/src/Symfony/Component/Security/Core/Tests/Authentication/Provider/UserAuthenticationProviderTest.php b/src/Symfony/Component/Security/Core/Tests/Authentication/Provider/UserAuthenticationProviderTest.php +index 1ce9b79..66c3697 100644 +--- a/src/Symfony/Component/Security/Core/Tests/Authentication/Provider/UserAuthenticationProviderTest.php ++++ b/src/Symfony/Component/Security/Core/Tests/Authentication/Provider/UserAuthenticationProviderTest.php +@@ -83,7 +83,7 @@ class UserAuthenticationProviderTest extends TestCase + + public function testAuthenticateWhenPreChecksFails() + { +- $this->expectException(CredentialsExpiredException::class); ++ $this->expectException(BadCredentialsException::class); + $userChecker = $this->createMock(UserCheckerInterface::class); + $userChecker->expects($this->once()) + ->method('checkPreAuth') +@@ -101,7 +101,7 @@ class UserAuthenticationProviderTest extends TestCase + + public function testAuthenticateWhenPostChecksFails() + { +- $this->expectException(AccountExpiredException::class); ++ $this->expectException(BadCredentialsException::class); + $userChecker = $this->createMock(UserCheckerInterface::class); + $userChecker->expects($this->once()) + ->method('checkPostAuth') +@@ -128,7 +128,7 @@ class UserAuthenticationProviderTest extends TestCase + ; + $provider->expects($this->once()) + ->method('checkAuthentication') +- ->willThrowException(new BadCredentialsException()) ++ ->willThrowException(new CredentialsExpiredException()) + ; + + $provider->authenticate($this->getSupportedToken()); +diff --git a/src/Symfony/Component/Security/Guard/Firewall/GuardAuthenticationListener.php b/src/Symfony/Component/Security/Guard/Firewall/GuardAuthenticationListener.php +index 45f20c3..4375fac 100644 +--- a/src/Symfony/Component/Security/Guard/Firewall/GuardAuthenticationListener.php ++++ b/src/Symfony/Component/Security/Guard/Firewall/GuardAuthenticationListener.php +@@ -17,7 +17,10 @@ use Symfony\Component\HttpFoundation\Response; + use Symfony\Component\HttpKernel\Event\RequestEvent; + use Symfony\Component\Security\Core\Authentication\AuthenticationManagerInterface; + use Symfony\Component\Security\Core\Authentication\Token\TokenInterface; ++use Symfony\Component\Security\Core\Exception\AccountStatusException; + use Symfony\Component\Security\Core\Exception\AuthenticationException; ++use Symfony\Component\Security\Core\Exception\BadCredentialsException; ++use Symfony\Component\Security\Core\Exception\UsernameNotFoundException; + use Symfony\Component\Security\Guard\AuthenticatorInterface; + use Symfony\Component\Security\Guard\GuardAuthenticatorHandler; + use Symfony\Component\Security\Guard\Token\PreAuthenticationGuardToken; +@@ -44,12 +47,13 @@ class GuardAuthenticationListener extends AbstractListener implements ListenerIn + private $guardAuthenticators; + private $logger; + private $rememberMeServices; ++ private $hideUserNotFoundExceptions; + + /** + * @param string $providerKey The provider (i.e. firewall) key + * @param iterable|AuthenticatorInterface[] $guardAuthenticators The authenticators, with keys that match what's passed to GuardAuthenticationProvider + */ +- public function __construct(GuardAuthenticatorHandler $guardHandler, AuthenticationManagerInterface $authenticationManager, string $providerKey, iterable $guardAuthenticators, LoggerInterface $logger = null) ++ public function __construct(GuardAuthenticatorHandler $guardHandler, AuthenticationManagerInterface $authenticationManager, string $providerKey, iterable $guardAuthenticators, LoggerInterface $logger = null, bool $hideUserNotFoundExceptions = true) + { + if (empty($providerKey)) { + throw new \InvalidArgumentException('$providerKey must not be empty.'); +@@ -60,6 +64,7 @@ class GuardAuthenticationListener extends AbstractListener implements ListenerIn + $this->providerKey = $providerKey; + $this->guardAuthenticators = $guardAuthenticators; + $this->logger = $logger; ++ $this->hideUserNotFoundExceptions = $hideUserNotFoundExceptions; + } + + /** +@@ -164,6 +169,12 @@ class GuardAuthenticationListener extends AbstractListener implements ListenerIn + $this->logger->info('Guard authentication failed.', ['exception' => $e, 'authenticator' => \get_class($guardAuthenticator)]); + } + ++ // Avoid leaking error details in case of invalid user (e.g. user not found or invalid account status) ++ // to prevent user enumeration via response content ++ if ($this->hideUserNotFoundExceptions && ($e instanceof UsernameNotFoundException || $e instanceof AccountStatusException)) { ++ $e = new BadCredentialsException('Bad credentials.', 0, $e); ++ } ++ + $response = $this->guardHandler->handleAuthenticationFailure($e, $request, $guardAuthenticator, $this->providerKey); + + if ($response instanceof Response) { +diff --git a/src/Symfony/Component/Security/Guard/Tests/Firewall/GuardAuthenticationListenerTest.php b/src/Symfony/Component/Security/Guard/Tests/Firewall/GuardAuthenticationListenerTest.php +index 7d1c8e7..512bf31 100644 +--- a/src/Symfony/Component/Security/Guard/Tests/Firewall/GuardAuthenticationListenerTest.php ++++ b/src/Symfony/Component/Security/Guard/Tests/Firewall/GuardAuthenticationListenerTest.php +@@ -19,6 +19,9 @@ use Symfony\Component\HttpKernel\Event\RequestEvent; + use Symfony\Component\Security\Core\Authentication\AuthenticationProviderManager; + use Symfony\Component\Security\Core\Authentication\Token\TokenInterface; + use Symfony\Component\Security\Core\Exception\AuthenticationException; ++use Symfony\Component\Security\Core\Exception\BadCredentialsException; ++use Symfony\Component\Security\Core\Exception\LockedException; ++use Symfony\Component\Security\Core\Exception\UsernameNotFoundException; + use Symfony\Component\Security\Guard\AuthenticatorInterface; + use Symfony\Component\Security\Guard\Firewall\GuardAuthenticationListener; + use Symfony\Component\Security\Guard\GuardAuthenticatorHandler; +@@ -211,6 +214,54 @@ class GuardAuthenticationListenerTest extends TestCase + $listener($this->event); + } + ++ /** ++ * @dataProvider exceptionsToHide ++ */ ++ public function testHandleHidesInvalidUserExceptions(AuthenticationException $exceptionToHide) ++ { ++ $authenticator = $this->createMock(AuthenticatorInterface::class); ++ $providerKey = 'my_firewall2'; ++ ++ $authenticator ++ ->expects($this->once()) ++ ->method('supports') ++ ->willReturn(true); ++ $authenticator ++ ->expects($this->once()) ++ ->method('getCredentials') ++ ->willReturn(['username' => 'robin', 'password' => 'hood']); ++ ++ $this->authenticationManager ++ ->expects($this->once()) ++ ->method('authenticate') ++ ->willThrowException($exceptionToHide); ++ ++ $this->guardAuthenticatorHandler ++ ->expects($this->once()) ++ ->method('handleAuthenticationFailure') ++ ->with($this->callback(function ($e) use ($exceptionToHide) { ++ return $e instanceof BadCredentialsException && $exceptionToHide === $e->getPrevious(); ++ }), $this->request, $authenticator, $providerKey); ++ ++ $listener = new GuardAuthenticationListener( ++ $this->guardAuthenticatorHandler, ++ $this->authenticationManager, ++ $providerKey, ++ [$authenticator], ++ $this->logger ++ ); ++ ++ $listener($this->event); ++ } ++ ++ public function exceptionsToHide() ++ { ++ return [ ++ [new UsernameNotFoundException()], ++ [new LockedException()], ++ ]; ++ } ++ + public function testSupportsReturnFalseSkipAuth() + { + $authenticator = $this->createMock(AuthenticatorInterface::class); diff --git a/debian/patches/series b/debian/patches/series index 7272d07179..de2ecb771a 100644 --- a/debian/patches/series +++ b/debian/patches/series @@ -18,3 +18,4 @@ ErrorHandler-Drop-currently-broken-assertions.patch Config-Drop-currently-broken-assertions.patch Workaround-failing-tests-with-php7.4.patch HttpClient-group-network-for-test-failing-without-vulcain.patch +Merge-branch-3.4-into-4.4.patch
signature.asc
Description: PGP signature