class CsrfRequestHeaderAccessCheck in Drupal 9
Same name and namespace in other branches
- 8 core/lib/Drupal/Core/Access/CsrfRequestHeaderAccessCheck.php \Drupal\Core\Access\CsrfRequestHeaderAccessCheck
Access protection against CSRF attacks.
Hierarchy
- class \Drupal\Core\Access\CsrfRequestHeaderAccessCheck implements AccessCheckInterface
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'
- core.services.yml in core/
core.services.yml - core/core.services.yml
1 service uses CsrfRequestHeaderAccessCheck
File
- core/
lib/ Drupal/ Core/ Access/ CsrfRequestHeaderAccessCheck.php, line 13
Namespace
Drupal\Core\AccessView 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
->getRequirements();
// Check for current requirement _csrf_request_header_token and deprecated
// REST requirement.
$applicable_requirements = [
'_csrf_request_header_token',
// @todo Remove _access_rest_csrf in Drupal 10.0.0 https://www.drupal.org/node/3115308
'_access_rest_csrf',
];
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 https://www.drupal.org/node/2772399', 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, [
'GET',
'HEAD',
'OPTIONS',
'TRACE',
]);
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
->getMethod();
// Read-only operations are always allowed.
if (in_array($method, [
'GET',
'HEAD',
'OPTIONS',
'TRACE',
], 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')
->setCacheMaxAge(0);
}
$csrf_token = $request->headers
->get('X-CSRF-Token');
// @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')
->setCacheMaxAge(0);
}
}
// Let other access checkers decide if the request is legit.
return AccessResult::allowed()
->setCacheMaxAge(0);
}
}
Members
Name | Modifiers | Type | Description | Overrides |
---|---|---|---|---|
CsrfRequestHeaderAccessCheck:: |
protected | property | The token generator. | |
CsrfRequestHeaderAccessCheck:: |
protected | property | The session configuration. | |
CsrfRequestHeaderAccessCheck:: |
public | function | Checks access. | |
CsrfRequestHeaderAccessCheck:: |
public | function |
Declares whether the access check applies to a specific route or not. Overrides AccessCheckInterface:: |
|
CsrfRequestHeaderAccessCheck:: |
constant | A string key that will used to designate the token used by this class. | ||
CsrfRequestHeaderAccessCheck:: |
public | function | Constructs a new rest CSRF access check. |