diff --git a/core/modules/update/src/Tests/UpdateContribTest.php b/core/modules/update/src/Tests/UpdateContribTest.php
index 923b5d5..88cf378 100644
--- a/core/modules/update/src/Tests/UpdateContribTest.php
+++ b/core/modules/update/src/Tests/UpdateContribTest.php
@@ -345,6 +345,9 @@ function testUpdateBrokenFetchURL() {
     );
     $this->config('update_test.settings')->set('system_info', $system_info)->save();
 
+    // Ensure that the update information is correct before testing.
+    $this->drupalGet('admin/reports/updates');
+
     $xml_mapping = array(
       'drupal' => '0.0',
       'aaa_update_test' => '1_0',
diff --git a/core/modules/update/src/Tests/UpdateCoreTest.php b/core/modules/update/src/Tests/UpdateCoreTest.php
index 799d5a9..baecde8 100644
--- a/core/modules/update/src/Tests/UpdateCoreTest.php
+++ b/core/modules/update/src/Tests/UpdateCoreTest.php
@@ -65,11 +65,17 @@ function testNoUpdatesAvailable() {
    */
   function testNormalUpdateAvailable() {
     $this->setSystemInfo('8.0.0');
+
+    // Ensure that the update check requires a token.
+    $this->drupalGet('admin/reports/updates/check');
+    $this->assertResponse(403, 'Accessing admin/reports/updates/check without a CSRF token results in access denied.');
+
     foreach (array(0, 1) as $minor_version) {
       foreach (array('-alpha1', '-beta1', '') as $extra_version) {
         $this->refreshUpdateStatus(array('drupal' => "$minor_version.1" . $extra_version));
         $this->standardTests();
-        $this->drupalGet('admin/reports/updates/check');
+        $this->drupalGet('admin/reports/updates');
+        $this->clickLink(t('Check manually'));
         $this->assertNoText(t('Security update required!'));
         $this->assertRaw(\Drupal::l("8.$minor_version.1" . $extra_version, Url::fromUri("http://example.com/drupal-8-$minor_version-1$extra_version-release")), 'Link to release appears.');
         $this->assertRaw(\Drupal::l(t('Download'), Url::fromUri("http://example.com/drupal-8-$minor_version-1$extra_version.tar.gz")), 'Link to download appears.');
@@ -131,7 +137,8 @@ function testMajorUpdateAvailable() {
           $this->setSystemInfo("8.$minor_version.$patch_version" . $extra_version);
           $this->refreshUpdateStatus(array('drupal' => '9'));
           $this->standardTests();
-          $this->drupalGet('admin/reports/updates/check');
+          $this->drupalGet('admin/reports/updates');
+          $this->clickLink(t('Check manually'));
           $this->assertNoText(t('Security update required!'));
           $this->assertRaw(\Drupal::l('9.0.0', Url::fromUri("http://example.com/drupal-9-0-0-release")), 'Link to release appears.');
           $this->assertRaw(\Drupal::l(t('Download'), Url::fromUri("http://example.com/drupal-9-0-0.tar.gz")), 'Link to download appears.');
diff --git a/core/modules/update/src/Tests/UpdateTestBase.php b/core/modules/update/src/Tests/UpdateTestBase.php
index 24eb2aa..7db5b23 100644
--- a/core/modules/update/src/Tests/UpdateTestBase.php
+++ b/core/modules/update/src/Tests/UpdateTestBase.php
@@ -67,7 +67,8 @@ protected function refreshUpdateStatus($xml_map, $url = 'update-test') {
     // Save the map for UpdateTestController::updateTest() to use.
     $this->config('update_test.settings')->set('xml_map', $xml_map)->save();
     // Manually check the update status.
-    $this->drupalGet('admin/reports/updates/check');
+    $this->drupalGet('admin/reports/updates');
+    $this->clickLink(t('Check manually'));
   }
 
   /**
diff --git a/core/modules/update/src/Tests/UpdateUploadTest.php b/core/modules/update/src/Tests/UpdateUploadTest.php
index 1605f2e..39b6944 100644
--- a/core/modules/update/src/Tests/UpdateUploadTest.php
+++ b/core/modules/update/src/Tests/UpdateUploadTest.php
@@ -30,6 +30,9 @@ protected function setUp() {
    * Tests upload, extraction, and update of a module.
    */
   public function testUploadModule() {
+    // Ensure that the update information is correct before testing.
+    update_get_available(TRUE);
+
     // Images are not valid archives, so get one and try to install it. We
     // need an extra variable to store the result of drupalGetTestFiles()
     // since reset() takes an argument by reference and passing in a constant
diff --git a/core/modules/update/update.install b/core/modules/update/update.install
index b2223f1..e810129 100644
--- a/core/modules/update/update.install
+++ b/core/modules/update/update.install
@@ -148,3 +148,20 @@ function _update_requirement_check($project, $type) {
   $requirement['value'] = \Drupal::l($requirement_label, new Url(_update_manager_access() ? 'update.report_update' : 'update.status'));
   return $requirement;
 }
+
+/**
+ * @addtogroup updates-8.1.x
+ * @{
+ */
+
+/**
+ * Rebuild the router to ensure admin/reports/updates/check has CSRF protection.
+ */
+function update_update_8001() {
+  // Empty update forces a call to drupal_flush_all_caches() which rebuilds the
+  // router.
+}
+
+/**
+ * @} End of "addtogroup updates-8.1.x".
+ */
diff --git a/core/modules/update/update.module b/core/modules/update/update.module
index 01db0a7..fadd2e4 100644
--- a/core/modules/update/update.module
+++ b/core/modules/update/update.module
@@ -567,7 +567,12 @@ function _update_project_status_sort($a, $b) {
  */
 function template_preprocess_update_last_check(&$variables) {
   $variables['time'] = \Drupal::service('date.formatter')->formatTimeDiffSince($variables['last']);
-  $variables['link'] = \Drupal::l(t('Check manually'), new Url('update.manual_status', array(), array('query' => \Drupal::destination()->getAsArray())));
+  $variables['link'] = [
+    '#type' => 'link',
+    '#title' => t('Check manually'),
+    '#url' => Url::fromRoute('update.manual_status', [], ['query' => \Drupal::destination()->getAsArray()]),
+  ];
+
 }
 
 /**
diff --git a/core/modules/update/update.routing.yml b/core/modules/update/update.routing.yml
index 0049396..d5b79ea 100644
--- a/core/modules/update/update.routing.yml
+++ b/core/modules/update/update.routing.yml
@@ -21,6 +21,7 @@ update.manual_status:
     _controller: '\Drupal\update\Controller\UpdateController::updateStatusManually'
   requirements:
     _permission: 'administer site configuration'
+    _csrf_token: 'TRUE'
 
 update.report_install:
   path: '/admin/reports/updates/install'
