diff options
author | Nicolas Grekas <nicolas.grekas@gmail.com> | 2015-03-30 10:41:59 +0200 |
---|---|---|
committer | Nicolas Grekas <nicolas.grekas@gmail.com> | 2015-03-30 10:41:59 +0200 |
commit | 05006144a36061d7a30ac4522e24f1b0a1ac82b6 (patch) | |
tree | 002375d131dcafcb932af718c35b35ec58019301 | |
parent | 2e43dea46f12839ed7131d459390c5bcf9f4cb77 (diff) | |
parent | 02b20eccaf64c7c3c138f89e91f0a83c90cebfa2 (diff) | |
download | symfony-security-05006144a36061d7a30ac4522e24f1b0a1ac82b6.zip symfony-security-05006144a36061d7a30ac4522e24f1b0a1ac82b6.tar.gz symfony-security-05006144a36061d7a30ac4522e24f1b0a1ac82b6.tar.bz2 |
Merge branch '2.7'
* 2.7: (29 commits)
[Validator] Added missing Hungarian translation
remove usage of deprecated class
Fix merge
Fix merge
CS: fixes
[Translation][Extractor] Allow extracting an array of files besides extracting a directory
[VarDumper] Fix dumping ThrowingCasterException
[Console][Table] Add support for colspan/rowspan + multiple header lines
Translator component has default domain for null implemented no need to have default translation domain logic in 3 different places
Displays friendly message if the event does not have any registered listeners
[VarDumper] Ctrl+click toggles-all and fix IE8 support
Implemented check on interface implementation
[Form] [TwigBridge] Bootstrap layout whitespace control
|Validator] Add PHPUnit hint in AbstractConstraintValidatorTest
[VarDumper] implement expand all on ALT+click
[WebProfilerBundle] Fixed collapsed profiler menu icons
[travis] Kill tests when a new commit has been pushed
fixed CS
Change behavior to mirror hash_equals() returning early if there is a length mismatch
CS fixing
...
Conflicts:
src/Symfony/Bridge/Twig/composer.json
src/Symfony/Bundle/FrameworkBundle/composer.json
src/Symfony/Bundle/SecurityBundle/Resources/config/security.xml
src/Symfony/Bundle/SecurityBundle/Resources/config/security_acl.xml
src/Symfony/Bundle/SecurityBundle/Resources/config/security_acl_dbal.xml
src/Symfony/Bundle/SecurityBundle/Resources/config/security_listeners.xml
src/Symfony/Bundle/SecurityBundle/Resources/config/security_rememberme.xml
src/Symfony/Bundle/TwigBundle/Extension/AssetsExtension.php
-rw-r--r-- | Core/Authentication/AuthenticationProviderManager.php | 6 | ||||
-rw-r--r-- | Core/Tests/Authentication/AuthenticationProviderManagerTest.php | 10 | ||||
-rw-r--r-- | Core/Util/StringUtils.php | 49 | ||||
-rw-r--r-- | Http/RememberMe/TokenBasedRememberMeServices.php | 2 |
4 files changed, 55 insertions, 12 deletions
diff --git a/Core/Authentication/AuthenticationProviderManager.php b/Core/Authentication/AuthenticationProviderManager.php index f713e8f..16de8da 100644 --- a/Core/Authentication/AuthenticationProviderManager.php +++ b/Core/Authentication/AuthenticationProviderManager.php @@ -48,6 +48,12 @@ class AuthenticationProviderManager implements AuthenticationManagerInterface throw new \InvalidArgumentException('You must at least add one authentication provider.'); } + foreach ($providers as $provider) { + if (!$provider instanceof AuthenticationProviderInterface) { + throw new \InvalidArgumentException(sprintf('Provider "%s" must implement the AuthenticationProviderInterface.', get_class($provider))); + } + } + $this->providers = $providers; $this->eraseCredentials = (bool) $eraseCredentials; } diff --git a/Core/Tests/Authentication/AuthenticationProviderManagerTest.php b/Core/Tests/Authentication/AuthenticationProviderManagerTest.php index df25874..cc8b7c0 100644 --- a/Core/Tests/Authentication/AuthenticationProviderManagerTest.php +++ b/Core/Tests/Authentication/AuthenticationProviderManagerTest.php @@ -27,6 +27,16 @@ class AuthenticationProviderManagerTest extends \PHPUnit_Framework_TestCase new AuthenticationProviderManager(array()); } + /** + * @expectedException \InvalidArgumentException + */ + public function testAuthenticateWithProvidersWithIncorrectInterface() + { + new AuthenticationProviderManager(array( + new \stdClass(), + )); + } + public function testAuthenticateWhenNoProviderSupportsToken() { $manager = new AuthenticationProviderManager(array( diff --git a/Core/Util/StringUtils.php b/Core/Util/StringUtils.php index e8f3e3b..e68347f 100644 --- a/Core/Util/StringUtils.php +++ b/Core/Util/StringUtils.php @@ -38,29 +38,56 @@ class StringUtils */ public static function equals($knownString, $userInput) { - $knownString = (string) $knownString; - $userInput = (string) $userInput; + // Avoid making unnecessary duplications of secret data + if (!is_string($knownString)) { + $knownString = (string) $knownString; + } + + if (!is_string($userInput)) { + $userInput = (string) $userInput; + } if (function_exists('hash_equals')) { return hash_equals($knownString, $userInput); } - $knownLen = strlen($knownString); - $userLen = strlen($userInput); + $knownLen = self::safeStrlen($knownString); + $userLen = self::safeStrlen($userInput); - // Extend the known string to avoid uninitialized string offsets - $knownString .= $userInput; + if ($userLen !== $knownLen) { + return false; + } - // Set the result to the difference between the lengths - $result = $knownLen - $userLen; + $result = 0; - // Note that we ALWAYS iterate over the user-supplied length - // This is to mitigate leaking length information - for ($i = 0; $i < $userLen; $i++) { + for ($i = 0; $i < $knownLen; $i++) { $result |= (ord($knownString[$i]) ^ ord($userInput[$i])); } // They are only identical strings if $result is exactly 0... return 0 === $result; } + + /** + * Returns the number of bytes in a string. + * + * @param string $string The string whose length we wish to obtain + * + * @return int + */ + public static function safeStrlen($string) + { + // Premature optimization + // Since this cannot be changed at runtime, we can cache it + static $funcExists = null; + if (null === $funcExists) { + $funcExists = function_exists('mb_strlen'); + } + + if ($funcExists) { + return mb_strlen($string, '8bit'); + } + + return strlen($string); + } } diff --git a/Http/RememberMe/TokenBasedRememberMeServices.php b/Http/RememberMe/TokenBasedRememberMeServices.php index 9042963..3fe39ac 100644 --- a/Http/RememberMe/TokenBasedRememberMeServices.php +++ b/Http/RememberMe/TokenBasedRememberMeServices.php @@ -54,7 +54,7 @@ class TokenBasedRememberMeServices extends AbstractRememberMeServices throw new \RuntimeException(sprintf('The UserProviderInterface implementation must return an instance of UserInterface, but returned "%s".', get_class($user))); } - if (true !== StringUtils::equals($hash, $this->generateCookieHash($class, $username, $expires, $user->getPassword()))) { + if (true !== StringUtils::equals($this->generateCookieHash($class, $username, $expires, $user->getPassword()), $hash)) { throw new AuthenticationException('The cookie\'s hash is invalid.'); } |