Skip to content

Commit 1246890

Browse files
committed
feature #53851 [Security] Ignore empty username or password login attempts (llupa)
This PR was squashed before being merged into the 7.1 branch. Discussion ---------- [Security] Ignore empty username or password login attempts | Q | A | ------------- | --- | Branch? | 7.1 | Bug fix? | no | New feature? | yes/no/improvement | Deprecations? | no | Issues | N/A | License | MIT ## Context A person going through Symfony docs for the first time wanted to create their own `LoginFormType` as a next step in their learning Symfony journey and noticed that you can submit empty username/password with form login. They wanted to disallow this and tried to add validation. To validate a login form is not so straight forward as it either needs to be done with a custom authenticator (complex validation) _or_ user provider if the data checks are simple. After a simple discussion in Symfony slack with `@wouterj` I am opening this PR. The approach to immediately ignore login attempts with empty username or empty password has already been introduced in Symfony 7.0 in [this commit](a3a3856#diff-87efdd98e1b9520c9397f27a3e11df0be6e12737a6d1c25ac3321f9dfdc9c5c4). As always, I am happy to apply changes as requested! Commits ------- a804ca1 [Security] Ignore empty username or password login attempts
2 parents b982c71 + a804ca1 commit 1246890

File tree

3 files changed

+33
-0
lines changed

3 files changed

+33
-0
lines changed

src/Symfony/Component/Security/Http/Authenticator/FormLoginAuthenticator.php

+8
Original file line numberDiff line numberDiff line change
@@ -129,12 +129,20 @@ private function getCredentials(Request $request): array
129129

130130
$credentials['username'] = trim($credentials['username']);
131131

132+
if ('' === $credentials['username']) {
133+
throw new BadRequestHttpException(sprintf('The key "%s" must be a non-empty string.', $this->options['username_parameter']));
134+
}
135+
132136
$request->getSession()->set(SecurityRequestAttributes::LAST_USERNAME, $credentials['username']);
133137

134138
if (!\is_string($credentials['password']) && (!\is_object($credentials['password']) || !method_exists($credentials['password'], '__toString'))) {
135139
throw new BadRequestHttpException(sprintf('The key "%s" must be a string, "%s" given.', $this->options['password_parameter'], \gettype($credentials['password'])));
136140
}
137141

142+
if ('' === (string) $credentials['password']) {
143+
throw new BadRequestHttpException(sprintf('The key "%s" must be a non-empty string.', $this->options['password_parameter']));
144+
}
145+
138146
return $credentials;
139147
}
140148

src/Symfony/Component/Security/Http/CHANGELOG.md

+1
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ CHANGELOG
66

77
* Add `#[IsCsrfTokenValid]` attribute
88
* Add CAS 2.0 access token handler
9+
* Make empty username or empty password on form login attempts return Bad Request (400)
910

1011
7.0
1112
---

src/Symfony/Component/Security/Http/Tests/Authenticator/FormLoginAuthenticatorTest.php

+24
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,30 @@ protected function setUp(): void
4242
$this->failureHandler = $this->createMock(AuthenticationFailureHandlerInterface::class);
4343
}
4444

45+
public function testHandleWhenUsernameEmpty()
46+
{
47+
$this->expectException(BadRequestHttpException::class);
48+
$this->expectExceptionMessage('The key "_username" must be a non-empty string.');
49+
50+
$request = Request::create('/login_check', 'POST', ['_username' => '', '_password' => 's$cr$t']);
51+
$request->setSession($this->createSession());
52+
53+
$this->setUpAuthenticator();
54+
$this->authenticator->authenticate($request);
55+
}
56+
57+
public function testHandleWhenPasswordEmpty()
58+
{
59+
$this->expectException(BadRequestHttpException::class);
60+
$this->expectExceptionMessage('The key "_password" must be a non-empty string.');
61+
62+
$request = Request::create('/login_check', 'POST', ['_username' => 'foo', '_password' => '']);
63+
$request->setSession($this->createSession());
64+
65+
$this->setUpAuthenticator();
66+
$this->authenticator->authenticate($request);
67+
}
68+
4569
/**
4670
* @dataProvider provideUsernamesForLength
4771
*/

0 commit comments

Comments
 (0)