diff options
author | Christian Flothmann <christian.flothmann@xabbuh.de> | 2015-11-10 16:18:07 +0100 |
---|---|---|
committer | Fabien Potencier <fabien.potencier@gmail.com> | 2015-11-23 11:02:49 +0100 |
commit | 846a13ad9d7b2078d9dcc3db8a176a17a9659f11 (patch) | |
tree | 3a432ec4427bb1e5f7e28c2810e9bca3cce71456 | |
parent | 1dabcc78193413d90a6a1eeaaf50764b67ac61af (diff) | |
download | symfony-security-846a13ad9d7b2078d9dcc3db8a176a17a9659f11.zip symfony-security-846a13ad9d7b2078d9dcc3db8a176a17a9659f11.tar.gz symfony-security-846a13ad9d7b2078d9dcc3db8a176a17a9659f11.tar.bz2 |
fix potential timing attack issue
-rw-r--r-- | Http/RememberMe/PersistentTokenBasedRememberMeServices.php | 3 | ||||
-rw-r--r-- | Http/RememberMe/TokenBasedRememberMeServices.php | 28 |
2 files changed, 4 insertions, 27 deletions
diff --git a/Http/RememberMe/PersistentTokenBasedRememberMeServices.php b/Http/RememberMe/PersistentTokenBasedRememberMeServices.php index f800668..0fffbfe 100644 --- a/Http/RememberMe/PersistentTokenBasedRememberMeServices.php +++ b/Http/RememberMe/PersistentTokenBasedRememberMeServices.php @@ -21,6 +21,7 @@ use Symfony\Component\Security\Core\Authentication\RememberMe\PersistentToken; use Symfony\Component\Security\Core\Authentication\Token\TokenInterface; use Symfony\Component\Security\Core\Util\SecureRandomInterface; use Psr\Log\LoggerInterface; +use Symfony\Component\Security\Core\Util\StringUtils; /** * Concrete implementation of the RememberMeServicesInterface which needs @@ -90,7 +91,7 @@ class PersistentTokenBasedRememberMeServices extends AbstractRememberMeServices list($series, $tokenValue) = $cookieParts; $persistentToken = $this->tokenProvider->loadTokenBySeries($series); - if ($persistentToken->getTokenValue() !== $tokenValue) { + if (!StringUtils::equals($persistentToken->getTokenValue(), $tokenValue)) { throw new CookieTheftException('This token was already used. The account is possibly compromised.'); } diff --git a/Http/RememberMe/TokenBasedRememberMeServices.php b/Http/RememberMe/TokenBasedRememberMeServices.php index de662fb..1aea5fd 100644 --- a/Http/RememberMe/TokenBasedRememberMeServices.php +++ b/Http/RememberMe/TokenBasedRememberMeServices.php @@ -17,6 +17,7 @@ use Symfony\Component\HttpFoundation\Response; use Symfony\Component\Security\Core\Authentication\Token\TokenInterface; use Symfony\Component\Security\Core\Exception\AuthenticationException; use Symfony\Component\Security\Core\User\UserInterface; +use Symfony\Component\Security\Core\Util\StringUtils; /** * Concrete implementation of the RememberMeServicesInterface providing @@ -53,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 !== $this->compareHashes($hash, $this->generateCookieHash($class, $username, $expires, $user->getPassword()))) { + if (!StringUtils::equals($this->generateCookieHash($class, $username, $expires, $user->getPassword()), $hash)) { throw new AuthenticationException('The cookie\'s hash is invalid.'); } @@ -65,31 +66,6 @@ class TokenBasedRememberMeServices extends AbstractRememberMeServices } /** - * Compares two hashes using a constant-time algorithm to avoid (remote) - * timing attacks. - * - * This is the same implementation as used in the BasePasswordEncoder. - * - * @param string $hash1 The first hash - * @param string $hash2 The second hash - * - * @return bool true if the two hashes are the same, false otherwise - */ - private function compareHashes($hash1, $hash2) - { - if (strlen($hash1) !== $c = strlen($hash2)) { - return false; - } - - $result = 0; - for ($i = 0; $i < $c; ++$i) { - $result |= ord($hash1[$i]) ^ ord($hash2[$i]); - } - - return 0 === $result; - } - - /** * {@inheritdoc} */ protected function onLoginSuccess(Request $request, Response $response, TokenInterface $token) |