17
17
use Symfony \Component \HttpKernel \Event \GetResponseEvent ;
18
18
use Symfony \Component \Security \Core \Authentication \AuthenticationManagerInterface ;
19
19
use Symfony \Component \Security \Core \Authentication \Token \TokenInterface ;
20
+ use Symfony \Component \Security \Core \Exception \AccountStatusException ;
20
21
use Symfony \Component \Security \Core \Exception \AuthenticationException ;
22
+ use Symfony \Component \Security \Core \Exception \BadCredentialsException ;
23
+ use Symfony \Component \Security \Core \Exception \UsernameNotFoundException ;
21
24
use Symfony \Component \Security \Guard \AbstractGuardAuthenticator ;
22
25
use Symfony \Component \Security \Guard \AuthenticatorInterface ;
23
26
use Symfony \Component \Security \Guard \GuardAuthenticatorHandler ;
@@ -40,6 +43,7 @@ class GuardAuthenticationListener implements ListenerInterface
40
43
private $ guardAuthenticators ;
41
44
private $ logger ;
42
45
private $ rememberMeServices ;
46
+ private $ hideUserNotFoundExceptions ;
43
47
44
48
/**
45
49
* @param GuardAuthenticatorHandler $guardHandler The Guard handler
@@ -48,7 +52,7 @@ class GuardAuthenticationListener implements ListenerInterface
48
52
* @param iterable|AuthenticatorInterface[] $guardAuthenticators The authenticators, with keys that match what's passed to GuardAuthenticationProvider
49
53
* @param LoggerInterface $logger A LoggerInterface instance
50
54
*/
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 )
52
56
{
53
57
if (empty ($ providerKey )) {
54
58
throw new \InvalidArgumentException ('$providerKey must not be empty. ' );
@@ -59,6 +63,7 @@ public function __construct(GuardAuthenticatorHandler $guardHandler, Authenticat
59
63
$ this ->providerKey = $ providerKey ;
60
64
$ this ->guardAuthenticators = $ guardAuthenticators ;
61
65
$ this ->logger = $ logger ;
66
+ $ this ->hideUserNotFoundExceptions = $ hideUserNotFoundExceptions ;
62
67
}
63
68
64
69
/**
@@ -163,6 +168,12 @@ private function executeGuardAuthenticator($uniqueGuardKey, GuardAuthenticatorIn
163
168
$ this ->logger ->info ('Guard authentication failed. ' , ['exception ' => $ e , 'authenticator ' => \get_class ($ guardAuthenticator )]);
164
169
}
165
170
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
+
166
177
$ response = $ this ->guardHandler ->handleAuthenticationFailure ($ e , $ request , $ guardAuthenticator , $ this ->providerKey );
167
178
168
179
if ($ response instanceof Response) {
0 commit comments