[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

Bug#988457: marked as done (unblock: symfony/4.4.19+dfsg-2)



Your message dated Thu, 13 May 2021 11:42:16 +0000
with message-id <E1lh9jM-0006Yi-JO@respighi.debian.org>
and subject line unblock symfony
has caused the Debian Bug report #988457,
regarding unblock: symfony/4.4.19+dfsg-2
to be marked as done.

This means that you claim that the problem has been dealt with.
If this is not the case it is now your responsibility to reopen the
Bug report if necessary, and/or fix the problem forthwith.

(NB: If you are a system administrator and have no idea what this
message is talking about, this may indicate a serious mail system
misconfiguration somewhere. Please contact owner@bugs.debian.org
immediately.)


-- 
988457: https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=988457
Debian Bug Tracking System
Contact owner@bugs.debian.org with problems
--- Begin Message ---
Package: release.debian.org
Severity: normal
User: release.debian.org@packages.debian.org
Usertags: unblock
X-Debbugs-Cc: team@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 <taffit@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.grekas@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

Attachment: signature.asc
Description: PGP signature


--- End Message ---
--- Begin Message ---
Unblocked.

--- End Message ---

Reply to: