diff --git a/core/includes/bootstrap.inc b/core/includes/bootstrap.inc index 05319e9..1a84eb4 100644 --- a/core/includes/bootstrap.inc +++ b/core/includes/bootstrap.inc @@ -622,9 +622,9 @@ function drupal_valid_test_ua($new_prefix = NULL) { // string. $http_user_agent = isset($_SERVER['HTTP_USER_AGENT']) ? $_SERVER['HTTP_USER_AGENT'] : NULL; $user_agent = isset($_COOKIE['SIMPLETEST_USER_AGENT']) ? $_COOKIE['SIMPLETEST_USER_AGENT'] : $http_user_agent; - if (isset($user_agent) && preg_match("/^(simpletest\d+):(.+):(.+)$/", $user_agent, $matches)) { - list(, $prefix, $salt, $hmac) = $matches; - $check_string = $prefix . ':' . $salt; + if (isset($user_agent) && preg_match("/^(simpletest\d+):(.+):(.+):(.+)$/", $user_agent, $matches)) { + list(, $prefix, $time, $salt, $hmac) = $matches; + $check_string = $prefix . ':' . $time . ':' . $salt; // Read the hash salt prepared by drupal_generate_test_ua(). // This function is called before settings.php is read and Drupal's error // handlers are set up. While Drupal's error handling may be properly @@ -638,9 +638,15 @@ function drupal_valid_test_ua($new_prefix = NULL) { $private_key = file_get_contents($key_file); // The file properties add more entropy not easily accessible to others. $key = $private_key . filectime(__FILE__) . fileinode(__FILE__); + $time_diff = REQUEST_TIME - $time; $test_hmac = Crypt::hmacBase64($check_string, $key); - // Check that the HMAC matches. - if ($hmac === $test_hmac) { + // Since we are making a local request a 600 second time window is allowed, + // and the HMAC must match. + // @todo the additional time check appears to not add any security and can + // cause random test fails for long running tests. See the discussion in + // https://www.drupal.org/node/2771547 for why it should be removed in a + // future version. + if ($time_diff >= 0 && $time_diff <= 600 && $hmac === $test_hmac) { $test_prefix = $prefix; } } @@ -671,7 +677,7 @@ function drupal_generate_test_ua($prefix) { else { // Generate and save a new hash salt for a test run. // Consumed by drupal_valid_test_ua() before settings.php is loaded. - $private_key = Crypt::randomBytesBase64(110); + $private_key = Crypt::randomBytesBase64(55); file_put_contents($key_file, $private_key); } // The file properties add more entropy not easily accessible to others. @@ -679,7 +685,7 @@ function drupal_generate_test_ua($prefix) { } // Generate a moderately secure HMAC based on the database credentials. $salt = uniqid('', TRUE); - $check_string = $prefix . ':' . $salt; + $check_string = $prefix . ':' . time() . ':' . $salt; return $check_string . ':' . Crypt::hmacBase64($check_string, $key); }