diff --git a/src/Symfony/Component/Security/Http/Authenticator/FormLoginAuthenticator.php b/src/Symfony/Component/Security/Http/Authenticator/FormLoginAuthenticator.php index 2609d0d0e141c..1893b00fe22fb 100644 --- a/src/Symfony/Component/Security/Http/Authenticator/FormLoginAuthenticator.php +++ b/src/Symfony/Component/Security/Http/Authenticator/FormLoginAuthenticator.php @@ -157,6 +157,10 @@ private function getCredentials(Request $request): array $request->getSession()->set(Security::LAST_USERNAME, $credentials['username']); + if (!\is_string($credentials['password']) && (!\is_object($credentials['password']) || !method_exists($credentials['password'], '__toString'))) { + throw new BadRequestHttpException(sprintf('The key "%s" must be a string, "%s" given.', $this->options['password_parameter'], \gettype($credentials['password']))); + } + return $credentials; } diff --git a/src/Symfony/Component/Security/Http/Tests/Authenticator/FormLoginAuthenticatorTest.php b/src/Symfony/Component/Security/Http/Tests/Authenticator/FormLoginAuthenticatorTest.php index aa1ae8a950ccf..ca0dd119b89ef 100644 --- a/src/Symfony/Component/Security/Http/Tests/Authenticator/FormLoginAuthenticatorTest.php +++ b/src/Symfony/Component/Security/Http/Tests/Authenticator/FormLoginAuthenticatorTest.php @@ -23,6 +23,7 @@ use Symfony\Component\Security\Http\Authenticator\FormLoginAuthenticator; use Symfony\Component\Security\Http\Authenticator\Passport\Badge\CsrfTokenBadge; use Symfony\Component\Security\Http\Authenticator\Passport\Badge\PasswordUpgradeBadge; +use Symfony\Component\Security\Http\Authenticator\Passport\Credentials\PasswordCredentials; use Symfony\Component\Security\Http\HttpUtils; use Symfony\Component\Security\Http\Tests\Authenticator\Fixtures\PasswordUpgraderProvider; @@ -126,6 +127,44 @@ public function testHandleNonStringUsernameWithToString($postOnly) $this->authenticator->authenticate($request); } + /** + * @dataProvider postOnlyDataProvider + */ + public function testHandleNonStringPasswordWithArray(bool $postOnly) + { + $this->expectException(BadRequestHttpException::class); + $this->expectExceptionMessage('The key "_password" must be a string, "array" given.'); + + $request = Request::create('/login_check', 'POST', ['_username' => 'foo', '_password' => []]); + $request->setSession($this->createSession()); + + $this->setUpAuthenticator(['post_only' => $postOnly]); + $this->authenticator->authenticate($request); + } + + /** + * @dataProvider postOnlyDataProvider + */ + public function testHandleNonStringPasswordWithToString(bool $postOnly) + { + $passwordObject = new class() { + public function __toString() + { + return 's$cr$t'; + } + }; + + $request = Request::create('/login_check', 'POST', ['_username' => 'foo', '_password' => $passwordObject]); + $request->setSession($this->createSession()); + + $this->setUpAuthenticator(['post_only' => $postOnly]); + $passport = $this->authenticator->authenticate($request); + + /** @var PasswordCredentials $credentialsBadge */ + $credentialsBadge = $passport->getBadge(PasswordCredentials::class); + $this->assertSame('s$cr$t', $credentialsBadge->getPassword()); + } + public static function postOnlyDataProvider() { yield [true];