Currently the equality operator is used throughout Drupal core when hash values are compared. As pointed out elsewhere this can result in false positives under certain circumstances. This can be the case when a hashing operation results in values which are interpreted as a number by PHP (type juggling).
The following grep
turns up all relevant hash/token comparisons in the code base excluding vendor directory and clear false positives (for example from the text token replacement system, aka token module):
$ find . -type f -and -not -name '*.js' -and -not -name '*.tokens.inc' -and -not -name 'token.api.php' -and -not -name PoHeader.php -and -not -path '*/vendor/*' | xargs git grep '[^=!]==[^=]' | grep -E 'token|hash' | cat -n
1 core/lib/Drupal/Core/Password/PhpassHashedPassword.php: return ($hash && $stored_hash == $hash);
2 core/modules/toolbar/src/Controller/ToolbarController.php: return AccessResult::allowedIf($this->currentUser()->hasPermission('access toolbar') && $hash == _toolbar_get_subtrees_hash($langcode))->cachePerPermissions();
3 core/modules/user/src/AccountForm.php: $user_pass_reset = $pass_reset = isset($_SESSION['pass_reset_' . $account->id()]) && (\Drupal::request()->query->get('pass-reset-token') == $_SESSION['pass_reset_' . $account->id()]);
4 core/modules/user/src/Controller/UserController.php: if ($timestamp <= $current && $current - $timestamp < $timeout && $user->id() && $timestamp >= $user->getLastLoginTime() && $hashed_pass == user_pass_rehash($user->getPassword(), $timestamp, $user->getLastLoginTime(), $user->id())) {
\Drupal\Component\Utility\Crypt::hashEquals()
wrapping around the constant time hash_equals() function.Crypt::hashEquals()
method.None.
API addition (Crypt::hashEquals()
).
As of PHP 5.6, the function hash_equals() was added to help prevent timing attack security issues.
All this does is provide a string comparison for the use inside of php.
I have made a patch that adds forward compatibility by checking the php version constants.
see: http://us3.php.net/manual/en/function.hash-equals.php
see: http://us3.php.net/manual/en/migration56.new-features.php
<?php
// use more secure hash_equal() that was introduced in php 5.6 and greater.
// see: http://php.net/manual/en/function.hash-equals.php.
if (PHP_MAJOR_VERSION > 4 && PHP_MINOR_VERSION > 5) {
return ($hash && hash_equals($stored_hash, $hash));
}
?>
I am checking the php constants instead of using a function_exists() to prevent the possibility of some attacker implementing their own hash_equals() function for php versions < 5.6.
Fixed
8.0 β°οΈ
user system
The issue particularly affects sites running on PHP version 5.6.0 or later.
After being applied to the 8.x branch, it should be considered for backport to the 7.x branch. Note: This tag should generally remain even after the backport has been written, approved, and committed.
It makes Drupal less vulnerable to abuse or misuse. Note, this is the preferred tag, though the Security tag has a large body of issues tagged to it. Do NOT publicly disclose security vulnerabilities; contact the security team instead. Anyone (whether security team or not) can apply this tag to security improvements that do not directly present a vulnerability e.g. hardening an API to add filtering to reduce a common mistake in contributed modules.
Not all content is available!
It's likely this issue predates Contrib.social: some issue and comment data are missing.