You are here

class CsrfRequestHeaderAccessCheck in Drupal 8

Same name and namespace in other branches
  1. 9 core/lib/Drupal/Core/Access/CsrfRequestHeaderAccessCheck.php \Drupal\Core\Access\CsrfRequestHeaderAccessCheck

Access protection against CSRF attacks.


Expanded class hierarchy of CsrfRequestHeaderAccessCheck

1 file declares its use of CsrfRequestHeaderAccessCheck
CsrfTokenController.php in core/modules/system/src/Controller/CsrfTokenController.php
1 string reference to 'CsrfRequestHeaderAccessCheck' in core/
1 service uses CsrfRequestHeaderAccessCheck
access_check.header.csrf in core/


core/lib/Drupal/Core/Access/CsrfRequestHeaderAccessCheck.php, line 13


View source
class CsrfRequestHeaderAccessCheck implements AccessCheckInterface {

   * A string key that will used to designate the token used by this class.
  const TOKEN_KEY = 'X-CSRF-Token request header';

   * The session configuration.
   * @var \Drupal\Core\Session\SessionConfigurationInterface
  protected $sessionConfiguration;

   * The token generator.
   * @var \Drupal\Core\Access\CsrfTokenGenerator
  protected $csrfToken;

   * Constructs a new rest CSRF access check.
   * @param \Drupal\Core\Session\SessionConfigurationInterface $session_configuration
   *   The session configuration.
   * @param \Drupal\Core\Access\CsrfTokenGenerator $csrf_token
   *   The token generator.
  public function __construct(SessionConfigurationInterface $session_configuration, CsrfTokenGenerator $csrf_token) {
    $this->sessionConfiguration = $session_configuration;
    $this->csrfToken = $csrf_token;

   * {@inheritdoc}
  public function applies(Route $route) {
    $requirements = $route

    // Check for current requirement _csrf_request_header_token and deprecated
    // REST requirement.
    $applicable_requirements = [
      // @todo Remove _access_rest_csrf in Drupal 10.0.0
    if ($route
      ->hasRequirement('_access_rest_csrf')) {
      @trigger_error('Route requirement _access_rest_csrf is deprecated in drupal:8.2.0 and is removed in drupal:10.0.0. Use _csrf_request_header_token instead. See', E_USER_DEPRECATED);
    $requirement_keys = array_keys($requirements);
    if (array_intersect($applicable_requirements, $requirement_keys)) {
      if (isset($requirements['_method'])) {

        // There could be more than one method requirement separated with '|'.
        $methods = explode('|', $requirements['_method']);

        // CSRF protection only applies to write operations, so we can filter
        // out any routes that require reading methods only.
        $write_methods = array_diff($methods, [
        if (empty($write_methods)) {
          return FALSE;

      // No method requirement given, so we run this access check to be on the
      // safe side.
      return TRUE;

   * Checks access.
   * @param \Symfony\Component\HttpFoundation\Request $request
   *   The request object.
   * @param \Drupal\Core\Session\AccountInterface $account
   *   The currently logged in account.
   * @return \Drupal\Core\Access\AccessResultInterface
   *   The access result.
  public function access(Request $request, AccountInterface $account) {
    $method = $request

    // Read-only operations are always allowed.
    if (in_array($method, [
    ], TRUE)) {
      return AccessResult::allowed();

    // This check only applies if
    // 1. the user was successfully authenticated and
    // 2. the request comes with a session cookie.
    if ($account
      ->isAuthenticated() && $this->sessionConfiguration
      ->hasSession($request)) {
      if (!$request->headers
        ->has('X-CSRF-Token')) {
        return AccessResult::forbidden()
          ->setReason('X-CSRF-Token request header is missing')
      $csrf_token = $request->headers

      // @todo Remove validate call using 'rest' in 8.3.
      //   Kept here for sessions active during update.
      if (!$this->csrfToken
        ->validate($csrf_token, self::TOKEN_KEY) && !$this->csrfToken
        ->validate($csrf_token, 'rest')) {
        return AccessResult::forbidden()
          ->setReason('X-CSRF-Token request header is invalid')

    // Let other access checkers decide if the request is legit.
    return AccessResult::allowed()



Namesort descending Modifiers Type Description Overrides
CsrfRequestHeaderAccessCheck::$csrfToken protected property The token generator.
CsrfRequestHeaderAccessCheck::$sessionConfiguration protected property The session configuration.
CsrfRequestHeaderAccessCheck::access public function Checks access.
CsrfRequestHeaderAccessCheck::applies public function Declares whether the access check applies to a specific route or not. Overrides AccessCheckInterface::applies
CsrfRequestHeaderAccessCheck::TOKEN_KEY constant A string key that will used to designate the token used by this class.
CsrfRequestHeaderAccessCheck::__construct public function Constructs a new rest CSRF access check.