8000 [Security] Fix fatal error on non string username · symfony/symfony@6894e56 · GitHub
[go: up one dir, main page]

Skip to content

Commit 6894e56

Browse files
author
Robin Chalas
committed
[Security] Fix fatal error on non string username
1 parent 28485af commit 6894e56

File tree

3 files changed

+53
-12
lines changed

3 files changed

+53
-12
lines changed

src/Symfony/Component/Security/Http/Firewall/SimpleFormAuthenticationListener.php

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
use Symfony\Component\Form\Extension\Csrf\CsrfProvider\CsrfProviderAdapter;
1616
use Symfony\Component\Form\Extension\Csrf\CsrfProvider\CsrfProviderInterface;
1717
use Symfony\Component\HttpFoundation\Request;
18+
use Symfony\Component\HttpKernel\Exception\BadRequestHttpException;
1819
use Symfony\Component\Security\Core\Exception\InvalidArgumentException;
1920
use Symfony\Component\Security\Core\Exception\InvalidCsrfTokenException;
2021
use Symfony\Component\Security\Csrf\CsrfToken;
@@ -107,14 +108,16 @@ protected function attemptAuthentication(Request $request)
107108
}
108109
}
109110

110-
if ($this->options['post_only']) {
111-
$username = trim($request->request->get($this->options['username_parameter'], null, true));
112-
$password = $request->request->get($this->options['password_parameter'], null, true);
113-
} else {
114-
$username = trim($request->get($this->options['username_parameter'], null, true));
115-
$password = $request->get($this->options['password_parameter'], null, true);
111+
$requestBag = $this->options['post_only'] ? $request->request : $request;
112+
$username = $requestBag->get($this->options['username_parameter'], null, true);
113+
$password = $requestBag->get($this->options['password_parameter'], null, true);
114+
115+
if (!is_string($username)) {
116+
throw new BadRequestHttpException(sprintf('The key "%s" must be a string.', $this->options['username_parameter']));
116117
}
117118

119+
$username = trim($username);
120+
118121
if (strlen($username) > Security::MAX_USERNAME_LENGTH) {
119122
throw new BadCredentialsException('Invalid username.');
120123
}

src/Symfony/Component/Security/Http/Firewall/UsernamePasswordFormAuthenticationListener.php

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
use Symfony\Component\Form\Extension\Csrf\CsrfProvider\CsrfProviderInterface;
1616
use Symfony\Component\HttpFoundation\Request;
1717
use Psr\Log\LoggerInterface;
18+
use Symfony\Component\HttpKernel\Exception\BadRequestHttpException;
1819
use Symfony\Component\Security\Csrf\CsrfToken;
1920
use Symfony\Component\Security\Csrf\CsrfTokenManagerInterface;
2021
use Symfony\Component\Security\Http\Authentication\AuthenticationFailureHandlerInterface;
@@ -84,14 +85,16 @@ protected function attemptAuthentication(Request $request)
8485
}
8586
}
8687

87-
if ($this->options['post_only']) {
88-
$username = trim($request->request->get($this->options['username_parameter'], null, true));
89-
$password = $request->request->get($this->options['password_parameter'], null, true);
90-
} else {
91-
$username = trim($request->get($this->options['username_parameter'], null, true));
92-
$password = $request->get($this->options['password_parameter'], null, true);
88+
$requestBag = $this->options['post_only'] ? $request->request : $request;
89+
$username = $requestBag->get($this->options['username_parameter'], null, true);
90+
$password = $requestBag->get($this->options['password_parameter'], null, true);
91+
92+
if (!is_string($username)) {
93+
throw new BadRequestHttpException(sprintf('The key "%s" must be a string.', $this->options['username_parameter']));
9394
}
9495

96+
$username = trim($username);
97+
9598
if (strlen($username) > Security::MAX_USERNAME_LENGTH) {
9699
throw new BadCredentialsException('Invalid username.');
97100
}

src/Symfony/Component/Security/Http/Tests/Firewall/UsernamePasswordFormAuthenticationListenerTest.php

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,8 +14,13 @@
1414
use PHPUnit\Framework\TestCase;
1515
use Symfony\Component\HttpFoundation\Request;
1616
use Symfony\Component\HttpFoundation\Response;
17+
use Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorage;
18+
use Symfony\Component\Security\Http\Authentication\DefaultAuthenticationFailureHandler;
19+
use Symfony\Component\Security\Http\Authentication\DefaultAuthenticationSuccessHandler;
1720
use Symfony\Component\Security\Http\Firewall\UsernamePasswordFormAuthenticationListener;
1821
use Symfony\Component\Security\Core\SecurityContextInterface;
22+
use Symfony\Component\Security\Http\HttpUtils;
23+
use Symfony\Component\Security\Http\Session\SessionAuthenticationStrategy;
1924

2025
class UsernamePasswordFormAuthenticationListenerTest extends TestCase
2126
{
@@ -69,6 +74,36 @@ public function testHandleWhenUsernameLength($username, $ok)
6974
$listener->handle($event);
7075
}
7176

77+
/**
78+
* @expectedException \Symfony\Component\HttpKernel\Exception\BadRequestHttpException
79+
* @expectedExceptionMessage The key "_username" must be a string.
80+
*/
81+
public function testHandleNonStringUsername()
82+
{
83+
$request = Request::create('/login_check', 'POST', array('_username' => array()));
84+
$request->setSession($this->getMockBuilder('Symfony\Component\HttpFoundation\Session\SessionInterface')->getMock());
85+
86+
$listener = new UsernamePasswordFormAuthenticationListener(
87+
new TokenStorage(),
88+
$this->getMockBuilder('Symfony\Component\Security\Core\Authentication\AuthenticationManagerInterface')->getMock(),
89+
new SessionAuthenticationStrategy(SessionAuthenticationStrategy::NONE),
90+
$httpUtils = new HttpUtils(),
91+
'foo',
92+
new DefaultAuthenticationSuccessHandler($httpUtils),
93+
new DefaultAuthenticationFailureHandler($this->getMockBuilder('Symfony\Component\HttpKernel\HttpKernelInterface')->getMock(), $httpUtils),
94+
array('require_previous_session' => false)
95+
);
96+
97+
$event = $this->getMockBuilder('Symfony\Component\HttpKernel\Event\GetResponseEvent')->disableOriginalConstructor()->getMock();
98+
$event
99+
->expects($this->any())
100+
->method('getRequest')
101+
->will($this->returnValue($request))
102+
;
103+
104+
$listener->handle($event);
105+
}
106+
72107
public function getUsernameForLength()
73108
{
74109
return array(

0 commit comments

Comments
 (0)
0