From 7f1a4713d1c96afb608bce443fb3161bc8a4b498 Mon Sep 17 00:00:00 2001 From: Shawn Iwinski Date: Tue, 19 Apr 2016 14:38:18 -0400 Subject: [Security] Normalize "symfony/security-acl" dependency versions across all composer.json files --- composer.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/composer.json b/composer.json index 8764ce6..3eab48b 100644 --- a/composer.json +++ b/composer.json @@ -17,7 +17,7 @@ ], "require": { "php": ">=5.3.9", - "symfony/security-acl": "~2.7", + "symfony/security-acl": "~2.7|~3.0.0", "symfony/event-dispatcher": "~2.2|~3.0.0", "symfony/http-foundation": "~2.1|~3.0.0", "symfony/http-kernel": "~2.4|~3.0.0", -- cgit v1.1 From 5f0f6f3d66a5e6d1a3f73094335f6acdc23372c1 Mon Sep 17 00:00:00 2001 From: Daniel Espendiller Date: Mon, 2 May 2016 19:21:33 +0200 Subject: add @Event annotation for AuthenticationEvents --- Core/AuthenticationEvents.php | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/Core/AuthenticationEvents.php b/Core/AuthenticationEvents.php index 90b7142..13bce30 100644 --- a/Core/AuthenticationEvents.php +++ b/Core/AuthenticationEvents.php @@ -20,6 +20,8 @@ final class AuthenticationEvents * The event listener method receives a * Symfony\Component\Security\Core\Event\AuthenticationEvent instance. * + * @Event + * * @var string */ const AUTHENTICATION_SUCCESS = 'security.authentication.success'; @@ -32,6 +34,8 @@ final class AuthenticationEvents * Symfony\Component\Security\Core\Event\AuthenticationFailureEvent * instance. * + * @Event + * * @var string */ const AUTHENTICATION_FAILURE = 'security.authentication.failure'; -- cgit v1.1 From b30108120781893f72f15af4b8ab297aee05432c Mon Sep 17 00:00:00 2001 From: Erik van Wingerden Date: Mon, 9 May 2016 09:52:08 +0200 Subject: [2.3][Component/Security] Fixed phpdoc in AnonymousToken constructor for user param --- Core/Authentication/Token/AnonymousToken.php | 2 +- Core/Authentication/Token/PreAuthenticatedToken.php | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Core/Authentication/Token/AnonymousToken.php b/Core/Authentication/Token/AnonymousToken.php index 571816c..5f3241f 100644 --- a/Core/Authentication/Token/AnonymousToken.php +++ b/Core/Authentication/Token/AnonymousToken.php @@ -26,7 +26,7 @@ class AnonymousToken extends AbstractToken * Constructor. * * @param string $key The key shared with the authentication provider - * @param string $user The user + * @param string|object $user The user can be a UserInterface instance, or an object implementing a __toString method or the username as a regular string. * @param RoleInterface[] $roles An array of roles */ public function __construct($key, $user, array $roles = array()) diff --git a/Core/Authentication/Token/PreAuthenticatedToken.php b/Core/Authentication/Token/PreAuthenticatedToken.php index 1798203..5a3fc95 100644 --- a/Core/Authentication/Token/PreAuthenticatedToken.php +++ b/Core/Authentication/Token/PreAuthenticatedToken.php @@ -26,7 +26,7 @@ class PreAuthenticatedToken extends AbstractToken /** * Constructor. * - * @param string|object $user The user + * @param string|object $user The user can be a UserInterface instance, or an object implementing a __toString method or the username as a regular string. * @param mixed $credentials The user credentials * @param string $providerKey The provider key * @param RoleInterface[]|string[] $roles An array of roles -- cgit v1.1 From 83b345fdf01cb980fb8bd5e15224573d93b8e369 Mon Sep 17 00:00:00 2001 From: Fabien Potencier Date: Sun, 1 May 2016 06:13:23 +0200 Subject: limited the maximum length of a submitted username --- Core/SecurityContextInterface.php | 1 + .../UsernamePasswordFormAuthenticationListener.php | 5 ++ ...rnamePasswordFormAuthenticationListenerTest.php | 78 ++++++++++++++++++++++ 3 files changed, 84 insertions(+) create mode 100644 Tests/Http/Firewall/UsernamePasswordFormAuthenticationListenerTest.php diff --git a/Core/SecurityContextInterface.php b/Core/SecurityContextInterface.php index 50c30bb..0253a6a 100644 --- a/Core/SecurityContextInterface.php +++ b/Core/SecurityContextInterface.php @@ -23,6 +23,7 @@ interface SecurityContextInterface const ACCESS_DENIED_ERROR = '_security.403_error'; const AUTHENTICATION_ERROR = '_security.last_error'; const LAST_USERNAME = '_security.last_username'; + const MAX_USERNAME_LENGTH = 4096; /** * Returns the current security token. diff --git a/Http/Firewall/UsernamePasswordFormAuthenticationListener.php b/Http/Firewall/UsernamePasswordFormAuthenticationListener.php index 2147817..26aeb67 100644 --- a/Http/Firewall/UsernamePasswordFormAuthenticationListener.php +++ b/Http/Firewall/UsernamePasswordFormAuthenticationListener.php @@ -20,6 +20,7 @@ use Symfony\Component\Security\Http\Session\SessionAuthenticationStrategyInterfa use Symfony\Component\Security\Http\HttpUtils; use Symfony\Component\Security\Core\Authentication\AuthenticationManagerInterface; use Symfony\Component\Security\Core\Authentication\Token\UsernamePasswordToken; +use Symfony\Component\Security\Core\Exception\BadCredentialsException; use Symfony\Component\Security\Core\Exception\InvalidCsrfTokenException; use Symfony\Component\Security\Core\SecurityContextInterface; use Symfony\Component\EventDispatcher\EventDispatcherInterface; @@ -83,6 +84,10 @@ class UsernamePasswordFormAuthenticationListener extends AbstractAuthenticationL $password = $request->get($this->options['password_parameter'], null, true); } + if (strlen($username) > SecurityContextInterface::MAX_USERNAME_LENGTH) { + throw new BadCredentialsException('Invalid username.'); + } + $request->getSession()->set(SecurityContextInterface::LAST_USERNAME, $username); return $this->authenticationManager->authenticate(new UsernamePasswordToken($username, $password, $this->providerKey)); diff --git a/Tests/Http/Firewall/UsernamePasswordFormAuthenticationListenerTest.php b/Tests/Http/Firewall/UsernamePasswordFormAuthenticationListenerTest.php new file mode 100644 index 0000000..b7c6ab9 --- /dev/null +++ b/Tests/Http/Firewall/UsernamePasswordFormAuthenticationListenerTest.php @@ -0,0 +1,78 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Security\Tests\Http\Firewall; + +use Symfony\Component\HttpFoundation\Request; +use Symfony\Component\HttpFoundation\Response; +use Symfony\Component\Security\Http\Firewall\UsernamePasswordFormAuthenticationListener; +use Symfony\Component\Security\Core\SecurityContextInterface; + +class UsernamePasswordFormAuthenticationListenerTest extends \PHPUnit_Framework_TestCase +{ + /** + * @dataProvider getUsernameForLength + */ + public function testHandleWhenUsernameLength($username, $ok) + { + $request = Request::create('/login_check', 'POST', array('_username' => $username)); + $request->setSession($this->getMock('Symfony\Component\HttpFoundation\Session\SessionInterface')); + + $httpUtils = $this->getMock('Symfony\Component\Security\Http\HttpUtils'); + $httpUtils + ->expects($this->any()) + ->method('checkRequestPath') + ->will($this->returnValue(true)) + ; + + $failureHandler = $this->getMock('Symfony\Component\Security\Http\Authentication\AuthenticationFailureHandlerInterface'); + $failureHandler + ->expects($ok ? $this->never() : $this->once()) + ->method('onAuthenticationFailure') + ->will($this->returnValue(new Response())) + ; + + $authenticationManager = $this->getMockBuilder('Symfony\Component\Security\Core\Authentication\AuthenticationProviderManager')->disableOriginalConstructor()->getMock(); + $authenticationManager + ->expects($ok ? $this->once() : $this->never()) + ->method('authenticate') + ->will($this->returnValue(new Response())) + ; + + $listener = new UsernamePasswordFormAuthenticationListener( + $this->getMock('Symfony\Component\Security\Core\SecurityContextInterface'), + $authenticationManager, + $this->getMock('Symfony\Component\Security\Http\Session\SessionAuthenticationStrategyInterface'), + $httpUtils, + 'TheProviderKey', + $this->getMock('Symfony\Component\Security\Http\Authentication\AuthenticationSuccessHandlerInterface'), + $failureHandler, + array('require_previous_session' => false) + ); + + $event = $this->getMock('Symfony\Component\HttpKernel\Event\GetResponseEvent', array(), array(), '', false); + $event + ->expects($this->any()) + ->method('getRequest') + ->will($this->returnValue($request)) + ; + + $listener->handle($event); + } + + public function getUsernameForLength() + { + return array( + array(str_repeat('x', SecurityContextInterface::MAX_USERNAME_LENGTH + 1), false), + array(str_repeat('x', SecurityContextInterface::MAX_USERNAME_LENGTH - 1), true), + ); + } +} -- cgit v1.1 From 41bd59c6e04c433c9d0bcd53d8524226fb3aeb3a Mon Sep 17 00:00:00 2001 From: Charles Sarrazin Date: Thu, 18 Feb 2016 12:25:21 +0100 Subject: Fixed issue with blank password with Ldap The bind operation of LDAP, as described in RFC 4513, provides a method which allows for authentication of users. For the Simple Authentication Method a user may use the anonymous authentication mechanism, the unauthenticated authentication mechanism, or the name/password authentication mechanism. The unauthenticated authentication mechanism is used when a client who desires to establish an anonymous authorization state passes a non-zero length distinguished name and a zero length password. Most LDAP servers either can be configured to allow this mechanism or allow it by default. _Web-based applications which perform the simple bind operation with the client's credentials are at risk when an anonymous authorization state is established. This can occur when the web-based application passes a distinguished name and a zero length password to the LDAP server._ Thus, misconfiguring a server with simple bind can trick Symfony into thinking the username/password tuple as valid, potentially leading to unauthorized access. --- .../Provider/LdapBindAuthenticationProvider.php | 4 ++++ .../Provider/LdapBindAuthenticationProviderTest.php | 19 ++++++++++++++++++- 2 files changed, 22 insertions(+), 1 deletion(-) diff --git a/Core/Authentication/Provider/LdapBindAuthenticationProvider.php b/Core/Authentication/Provider/LdapBindAuthenticationProvider.php index adc42ef..e887f99 100644 --- a/Core/Authentication/Provider/LdapBindAuthenticationProvider.php +++ b/Core/Authentication/Provider/LdapBindAuthenticationProvider.php @@ -73,6 +73,10 @@ class LdapBindAuthenticationProvider extends UserAuthenticationProvider $username = $token->getUsername(); $password = $token->getCredentials(); + if ('' === $password) { + throw new BadCredentialsException('The presented password must not be empty.'); + } + try { $username = $this->ldap->escape($username, '', LDAP_ESCAPE_DN); $dn = str_replace('{username}', $username, $this->dnString); diff --git a/Core/Tests/Authentication/Provider/LdapBindAuthenticationProviderTest.php b/Core/Tests/Authentication/Provider/LdapBindAuthenticationProviderTest.php index 844bcef..fbb4d73 100644 --- a/Core/Tests/Authentication/Provider/LdapBindAuthenticationProviderTest.php +++ b/Core/Tests/Authentication/Provider/LdapBindAuthenticationProviderTest.php @@ -23,6 +23,23 @@ class LdapBindAuthenticationProviderTest extends \PHPUnit_Framework_TestCase { /** * @expectedException \Symfony\Component\Security\Core\Exception\BadCredentialsException + * @expectedExceptionMessage The presented password must not be empty. + */ + public function testEmptyPasswordShouldThrowAnException() + { + $userProvider = $this->getMock('Symfony\Component\Security\Core\User\UserProviderInterface'); + $ldap = $this->getMock('Symfony\Component\Ldap\LdapClientInterface'); + $userChecker = $this->getMock('Symfony\Component\Security\Core\User\UserCheckerInterface'); + + $provider = new LdapBindAuthenticationProvider($userProvider, $userChecker, 'key', $ldap); + $reflection = new \ReflectionMethod($provider, 'checkAuthentication'); + $reflection->setAccessible(true); + + $reflection->invoke($provider, new User('foo', null), new UsernamePasswordToken('foo', '', 'key')); + } + + /** + * @expectedException \Symfony\Component\Security\Core\Exception\BadCredentialsException * @expectedExceptionMessage The presented password is invalid. */ public function testBindFailureShouldThrowAnException() @@ -40,7 +57,7 @@ class LdapBindAuthenticationProviderTest extends \PHPUnit_Framework_TestCase $reflection = new \ReflectionMethod($provider, 'checkAuthentication'); $reflection->setAccessible(true); - $reflection->invoke($provider, new User('foo', null), new UsernamePasswordToken('foo', '', 'key')); + $reflection->invoke($provider, new User('foo', null), new UsernamePasswordToken('foo', 'bar', 'key')); } public function testRetrieveUser() -- cgit v1.1