From 20ba39f767f6f0e25f1895ffd2dfb1ce510ac060 Mon Sep 17 00:00:00 2001 From: Lee Rowlands Date: Wed, 5 Jun 2019 09:13:24 +1000 Subject: [PATCH] Issue #3057314 by alexpott, chr.fritsch, larowlan: Harden hash checking in core (cherry picked from commit cf939a5dc0ab6a3f99b2058df49d98f8259b92a8) --- core/includes/bootstrap.inc | 2 +- core/modules/file/src/Element/ManagedFile.php | 3 ++- .../image/src/Controller/ImageStyleDownloadController.php | 2 +- .../system/src/Controller/EntityAutocompleteController.php | 2 +- 4 files changed, 5 insertions(+), 4 deletions(-) diff --git a/core/includes/bootstrap.inc b/core/includes/bootstrap.inc index 9563facf28b..348724d6e7e 100644 --- a/core/includes/bootstrap.inc +++ b/core/includes/bootstrap.inc @@ -684,7 +684,7 @@ function drupal_valid_test_ua($new_prefix = NULL) { $test_hmac = Crypt::hmacBase64($check_string, $key); // Since we are making a local request a 600 second time window is allowed, // and the HMAC must match. - if ($time_diff >= 0 && $time_diff <= 600 && $hmac === $test_hmac) { + if ($time_diff >= 0 && $time_diff <= 600 && Crypt::hashEquals($test_hmac, $hmac)) { $test_prefix = $prefix; } else { diff --git a/core/modules/file/src/Element/ManagedFile.php b/core/modules/file/src/Element/ManagedFile.php index b26118916e5..3082136bf1e 100644 --- a/core/modules/file/src/Element/ManagedFile.php +++ b/core/modules/file/src/Element/ManagedFile.php @@ -110,7 +110,8 @@ class ManagedFile extends FormElement { // token added by $this->processManagedFile(). elseif (\Drupal::currentUser()->isAnonymous()) { $token = NestedArray::getValue($form_state->getUserInput(), array_merge($element['#parents'], ['file_' . $file->id(), 'fid_token'])); - if ($token !== Crypt::hmacBase64('file-' . $file->id(), \Drupal::service('private_key')->get() . Settings::getHashSalt())) { + $file_hmac = Crypt::hmacBase64('file-' . $file->id(), \Drupal::service('private_key')->get() . Settings::getHashSalt()); + if ($token === NULL || !Crypt::hashEquals($file_hmac, $token)) { $force_default = TRUE; break; } diff --git a/core/modules/image/src/Controller/ImageStyleDownloadController.php b/core/modules/image/src/Controller/ImageStyleDownloadController.php index 3d4ee1cc81e..d6e46155d6a 100644 --- a/core/modules/image/src/Controller/ImageStyleDownloadController.php +++ b/core/modules/image/src/Controller/ImageStyleDownloadController.php @@ -104,7 +104,7 @@ class ImageStyleDownloadController extends FileDownloadController { // starts with styles/. $valid = !empty($image_style) && file_stream_wrapper_valid_scheme($scheme); if (!$this->config('image.settings')->get('allow_insecure_derivatives') || strpos(ltrim($target, '\/'), 'styles/') === 0) { - $valid &= $request->query->get(IMAGE_DERIVATIVE_TOKEN) === $image_style->getPathToken($image_uri); + $valid &= Crypt::hashEquals($image_style->getPathToken($image_uri), $request->query->get(IMAGE_DERIVATIVE_TOKEN, '')); } if (!$valid) { // Return a 404 (Page Not Found) rather than a 403 (Access Denied) as the diff --git a/core/modules/system/src/Controller/EntityAutocompleteController.php b/core/modules/system/src/Controller/EntityAutocompleteController.php index 88c367f2822..fef61c3061a 100644 --- a/core/modules/system/src/Controller/EntityAutocompleteController.php +++ b/core/modules/system/src/Controller/EntityAutocompleteController.php @@ -87,7 +87,7 @@ class EntityAutocompleteController extends ControllerBase { $selection_settings = $this->keyValue->get($selection_settings_key, FALSE); if ($selection_settings !== FALSE) { $selection_settings_hash = Crypt::hmacBase64(serialize($selection_settings) . $target_type . $selection_handler, Settings::getHashSalt()); - if ($selection_settings_hash !== $selection_settings_key) { + if (!Crypt::hashEquals($selection_settings_hash, $selection_settings_key)) { // Disallow access when the selection settings hash does not match the // passed-in key. throw new AccessDeniedHttpException('Invalid selection settings key.');