diff options
author | Fabien Potencier <fabien.potencier@gmail.com> | 2015-03-27 11:19:51 +0100 |
---|---|---|
committer | Fabien Potencier <fabien.potencier@gmail.com> | 2015-03-27 11:19:51 +0100 |
commit | 94465e02e58f9a17b29dd4afbcac5c02af4bf7e0 (patch) | |
tree | c1655995142c2ce7edcf8a47f1e3f39f2d1e51dd /Core | |
parent | ee7e5319d0a164be841bf1651c51fc2d09b17698 (diff) | |
parent | 6c8c751f7f5b09dbb608d4f43518dcb3fb214057 (diff) | |
download | symfony-security-94465e02e58f9a17b29dd4afbcac5c02af4bf7e0.zip symfony-security-94465e02e58f9a17b29dd4afbcac5c02af4bf7e0.tar.gz symfony-security-94465e02e58f9a17b29dd4afbcac5c02af4bf7e0.tar.bz2 |
Merge branch '2.3' into 2.6
* 2.3:
CS: fixes
Translator component has default domain for null implemented no need to have default translation domain logic in 3 different places
[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
Prevent modifying secrets as much as possible
Update StringUtils.php
Whitespace
Update StringUtils.php
CS: general fixes
[SecurityBundle] removed a duplicated service definition and simplified others.
Conflicts:
src/Symfony/Bundle/FrameworkBundle/Resources/views/Form/choice_widget_collapsed.html.php
src/Symfony/Bundle/SecurityBundle/Resources/config/security_rememberme.xml
src/Symfony/Component/Console/Tests/Helper/LegacyTableHelperTest.php
src/Symfony/Component/DependencyInjection/Tests/Fixtures/php/services11.php
Diffstat (limited to 'Core')
-rw-r--r-- | Core/Util/StringUtils.php | 49 |
1 files changed, 38 insertions, 11 deletions
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); + } } |