1717use Symfony \Component \HttpKernel \Event \GetResponseEvent ;
1818use Symfony \Component \Security \Core \Authentication \AuthenticationManagerInterface ;
1919use Symfony \Component \Security \Core \Authentication \Token \TokenInterface ;
20+ use Symfony \Component \Security \Core \Exception \AccountStatusException ;
2021use Symfony \Component \Security \Core \Exception \AuthenticationException ;
22+ use Symfony \Component \Security \Core \Exception \BadCredentialsException ;
23+ use Symfony \Component \Security \Core \Exception \UsernameNotFoundException ;
2124use Symfony \Component \Security \Guard \AbstractGuardAuthenticator ;
2225use Symfony \Component \Security \Guard \AuthenticatorInterface ;
2326use Symfony \Component \Security \Guard \GuardAuthenticatorHandler ;
@@ -40,6 +43,7 @@ class GuardAuthenticationListener implements ListenerInterface
4043 private $ guardAuthenticators ;
4144 private $ logger ;
4245 private $ rememberMeServices ;
46+ private $ hideUserNotFoundExceptions ;
4347
4448 /**
4549 * @param GuardAuthenticatorHandler $guardHandler The Guard handler
@@ -48,7 +52,7 @@ class GuardAuthenticationListener implements ListenerInterface
4852 * @param iterable|AuthenticatorInterface[] $guardAuthenticators The authenticators, with keys that match what's passed to GuardAuthenticationProvider
4953 * @param LoggerInterface $logger A LoggerInterface instance
5054 */
51- public function __construct (GuardAuthenticatorHandler $ guardHandler , AuthenticationManagerInterface $ authenticationManager , $ providerKey , $ guardAuthenticators , LoggerInterface $ logger = null )
55+ public function __construct (GuardAuthenticatorHandler $ guardHandler , AuthenticationManagerInterface $ authenticationManager , $ providerKey , $ guardAuthenticators , LoggerInterface $ logger = null , $ hideUserNotFoundExceptions = true )
5256 {
5357 if (empty ($ providerKey )) {
5458 throw new \InvalidArgumentException ('$providerKey must not be empty. ' );
@@ -59,6 +63,7 @@ public function __construct(GuardAuthenticatorHandler $guardHandler, Authenticat
5963 $ this ->providerKey = $ providerKey ;
6064 $ this ->guardAuthenticators = $ guardAuthenticators ;
6165 $ this ->logger = $ logger ;
66+ $ this ->hideUserNotFoundExceptions = $ hideUserNotFoundExceptions ;
6267 }
6368
6469 /**
@@ -163,6 +168,12 @@ private function executeGuardAuthenticator($uniqueGuardKey, GuardAuthenticatorIn
163168 $ this ->logger ->info ('Guard authentication failed. ' , ['exception ' => $ e , 'authenticator ' => \get_class ($ guardAuthenticator )]);
164169 }
165170
171+ // Avoid leaking error details in case of invalid user (e.g. user not found or invalid account status)
172+ // to prevent user enumeration via response content
173+ if ($ this ->hideUserNotFoundExceptions && ($ e instanceof UsernameNotFoundException || $ e instanceof AccountStatusException)) {
174+ $ e = new BadCredentialsException ('Bad credentials. ' , 0 , $ e );
175+ }
176+
166177 $ response = $ this ->guardHandler ->handleAuthenticationFailure ($ e , $ request , $ guardAuthenticator , $ this ->providerKey );
167178
168179 if ($ response instanceof Response) {
0 commit comments