diff --git a/core/lib/Drupal/Core/Access/CSRFAccessCheck.php b/core/lib/Drupal/Core/Access/CSRFAccessCheck.php
new file mode 100644
index 0000000..12bc607
--- /dev/null
+++ b/core/lib/Drupal/Core/Access/CSRFAccessCheck.php
@@ -0,0 +1,35 @@
+<?php
+
+/**
+ * @file
+ * Contains Drupal\Core\Access\CSRFAccessCheck.
+ */
+
+namespace Drupal\Core\Access;
+
+use Symfony\Component\Routing\Route;
+use Symfony\Component\HttpFoundation\Request;
+
+/**
+ * Allows access to routes to be controlled by a '_csrf' parameter.
+ *
+ * To use this check, add a "token" GET parameter to URLs using
+ * drupal_get_token(), for which the parameter has the same value as the
+ * "_csrf" parameter in the route.
+ */
+class CSRFAccessCheck implements AccessCheckInterface {
+
+  /**
+   * Implements AccessCheckInterface::applies().
+   */
+  public function applies(Route $route) {
+    return array_key_exists('_csrf', $route->getRequirements());
+  }
+
+  /**
+   * Implements AccessCheckInterface::access().
+   */
+  public function access(Route $route, Request $request) {
+    return drupal_get_token($route->getRequirement('_csrf')) == $request->query->get('token');
+  }
+}
diff --git a/core/lib/Drupal/Core/CoreBundle.php b/core/lib/Drupal/Core/CoreBundle.php
index ee63bfa..e79e90c 100644
--- a/core/lib/Drupal/Core/CoreBundle.php
+++ b/core/lib/Drupal/Core/CoreBundle.php
@@ -255,6 +255,8 @@ public function build(ContainerBuilder $container) {
       ->addTag('event_subscriber');
     $container->register('access_check.default', 'Drupal\Core\Access\DefaultAccessCheck')
       ->addTag('access_check');
+    $container->register('access_check.csrf', 'Drupal\Core\Access\CSRFAccessCheck')
+      ->addTag('access_check');
     $container->register('maintenance_mode_subscriber', 'Drupal\Core\EventSubscriber\MaintenanceModeSubscriber')
       ->addTag('event_subscriber');
     $container->register('path_subscriber', 'Drupal\Core\EventSubscriber\PathSubscriber')
diff --git a/core/tests/Drupal/Tests/Core/Access/CSRFAccessCheckTest.php b/core/tests/Drupal/Tests/Core/Access/CSRFAccessCheckTest.php
new file mode 100644
index 0000000..95bfaf1
--- /dev/null
+++ b/core/tests/Drupal/Tests/Core/Access/CSRFAccessCheckTest.php
@@ -0,0 +1,65 @@
+<?php
+
+/**
+ * @file
+ * Contains \Drupal\Tests\Core\Access\CSRFAccessCheckTest.
+ */
+
+namespace Drupal\Tests\Core\Access;
+
+use Symfony\Component\HttpFoundation\Request;
+use Symfony\Component\Routing\Route;
+use Drupal\Core\Access\CSRFAccessCheck;
+use Drupal\Tests\UnitTestCase;
+
+/**
+ * Tests \Drupal\Core\Access\CSRFAccessCheck.
+ */
+class CSRFAccessCheckTest extends UnitTestCase {
+
+  public static function getInfo() {
+    return array(
+      'name' => '\Drupal\Tests\Core\Access\CSRFAccessCheck',
+      'group' => 'Access'
+    );
+  }
+
+  /**
+   * Tests CSRFAccessCheck::applies().
+   */
+  public function testApplies() {
+    $applies_check = new CSRFAccessCheck();
+
+    $route = $this->getMockBuilder('Symfony\Component\Routing\Route')
+      ->disableOriginalConstructor()
+      ->getMock();
+    $route->expects($this->any())
+      ->method('getRequirements')
+      ->will($this->returnValue(array('_csrf' => '')));
+    $res = $applies_check->applies($route);
+    $this->assertEquals(TRUE, $res);
+
+    $route = $this->getMockBuilder('Symfony\Component\Routing\Route')
+      ->disableOriginalConstructor()
+      ->getMock();
+    $route->expects($this->any())
+      ->method('getRequirements')
+      ->will($this->returnValue(array()));
+    $res = $applies_check->applies($route);
+    $this->assertEquals(FALSE, $res);
+  }
+
+  /**
+   * Tests CSRFAccessCheck::access().
+   */
+  public function testAccess() {
+    $token_value = 'b1rd';
+    $route = new Route('/foo', array(), array('_csrf: ' . $token_value));
+    $request = new Request(array(
+      'token' => drupal_get_token($token_value),
+    ));
+    $access_check = new CSRFAccessCheck();
+    $access = $access_check->access($route, $request);
+    $this->assertEquals(TRUE, $access);
+  }
+}
