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

Lines changed: 8 additions & 0 deletions
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

Lines changed: 1 addition & 0 deletions
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

Lines changed: 24 additions & 0 deletions
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)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy