Skip to content

Commit ca54e55

Browse files
core23chalasr
authored andcommitted
[Security][SecurityBundle] Show user account status errors
1 parent a96320c commit ca54e55

File tree

5 files changed

+591
-19
lines changed

5 files changed

+591
-19
lines changed

Authentication/AuthenticatorManager.php

Lines changed: 25 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,8 @@
4646
*/
4747
class AuthenticatorManager implements AuthenticatorManagerInterface, UserAuthenticatorInterface
4848
{
49+
private ExposeSecurityLevel $exposeSecurityErrors;
50+
4951
/**
5052
* @param iterable<mixed, AuthenticatorInterface> $authenticators
5153
*/
@@ -56,9 +58,17 @@ public function __construct(
5658
private string $firewallName,
5759
private ?LoggerInterface $logger = null,
5860
private bool $eraseCredentials = true,
59-
private bool $hideUserNotFoundExceptions = true,
61+
ExposeSecurityLevel|bool $exposeSecurityErrors = ExposeSecurityLevel::None,
6062
private array $requiredBadges = [],
6163
) {
64+
if (\is_bool($exposeSecurityErrors)) {
65+
trigger_deprecation('symfony/security-http', '7.3', 'Passing a boolean as "exposeSecurityErrors" parameter is deprecated, use %s value instead.', ExposeSecurityLevel::class);
66+
67+
// The old parameter had an inverted meaning ($hideUserNotFoundExceptions), for that reason the current name does not reflect the behavior
68+
$exposeSecurityErrors = $exposeSecurityErrors ? ExposeSecurityLevel::None : ExposeSecurityLevel::All;
69+
}
70+
71+
$this->exposeSecurityErrors = $exposeSecurityErrors;
6272
}
6373

6474
/**
@@ -250,7 +260,7 @@ private function handleAuthenticationFailure(AuthenticationException $authentica
250260

251261
// Avoid leaking error details in case of invalid user (e.g. user not found or invalid account status)
252262
// to prevent user enumeration via response content comparison
253-
if ($this->hideUserNotFoundExceptions && ($authenticationException instanceof UserNotFoundException || ($authenticationException instanceof AccountStatusException && !$authenticationException instanceof CustomUserMessageAccountStatusException))) {
263+
if ($this->isSensitiveException($authenticationException)) {
254264
$authenticationException = new BadCredentialsException('Bad credentials.', 0, $authenticationException);
255265
}
256266

@@ -264,4 +274,17 @@ private function handleAuthenticationFailure(AuthenticationException $authentica
264274
// returning null is ok, it means they want the request to continue
265275
return $loginFailureEvent->getResponse();
266276
}
277+
278+
private function isSensitiveException(AuthenticationException $exception): bool
279+
{
280+
if (ExposeSecurityLevel::All !== $this->exposeSecurityErrors && $exception instanceof UserNotFoundException) {
281+
return true;
282+
}
283+
284+
if (ExposeSecurityLevel::None === $this->exposeSecurityErrors && $exception instanceof AccountStatusException && !$exception instanceof CustomUserMessageAccountStatusException) {
285+
return true;
286+
}
287+
288+
return false;
289+
}
267290
}
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
<?php
2+
3+
/*
4+
* This file is part of the Symfony package.
5+
*
6+
* (c) Fabien Potencier <fabien@symfony.com>
7+
*
8+
* For the full copyright and license information, please view the LICENSE
9+
* file that was distributed with this source code.
10+
*/
11+
12+
namespace Symfony\Component\Security\Http\Authentication;
13+
14+
/**
15+
* @author Christian Gripp <mail@core23.de>
16+
*/
17+
enum ExposeSecurityLevel: string
18+
{
19+
case None = 'none';
20+
case AccountStatus = 'account_status';
21+
case All = 'all';
22+
}

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ CHANGELOG
55
---
66

77
* Add encryption support to `OidcTokenHandler` (JWE)
8+
* Replace `$hideAccountStatusExceptions` argument with `$exposeSecurityErrors` in `AuthenticatorManager` constructor
89

910
7.2
1011
---

0 commit comments

Comments
 (0)