Make it harder to have routes vulnerable to CSRF

Created on 20 February 2025, 2 months ago

Problem/Motivation

The security advisories list contains many fixed CSRF vulnerabilities. It proves that it is easy to forget to add CSRF protection on GET routes that do sensitive actions.

It is easy to create a route and simply forget to add CSRF protection to it.

Steps to reproduce

  1. Create a GET route that deletes an entity or changes a config value without a confirmation form.
  2. Don't add the _csrf_token requirement.
  3. Your route is vulnerable to CSRF attacks.

Proposed resolution

Adding CSRF tokens to every GET route would not be a good idea, it is only needed on routes that modify config or entities.
But maybe we could make it required to specify explicitly on each route whether it needs CSRF token. (Similar for what we do for access checks on entity queries.)
This would force developers to think about it.

(Routes that return a form are already protected from CSRF attacks automatically and would not need this.)

An alternative approach would be to forbid sensitives actions in GET requests ( 📌 CSRF tokens in GET requests can be leaked and reused; stop encouraging server-site state changes with GET requests Active ) but I don't think this would be easy to do.

Remaining tasks

User interface changes

Introduced terminology

API changes

Data model changes

Release notes snippet

Feature request
Status

Active

Version

11.1 🔥

Component

routing system

Created by

🇫🇷France prudloff Lille

Live updates comments and jobs are added and updated live.
  • Security improvements

    It makes Drupal less vulnerable to abuse or misuse. Note, this is the preferred tag, though the Security tag has a large body of issues tagged to it. Do NOT publicly disclose security vulnerabilities; contact the security team instead. Anyone (whether security team or not) can apply this tag to security improvements that do not directly present a vulnerability e.g. hardening an API to add filtering to reduce a common mistake in contributed modules.

Sign in to follow issues

Merge Requests

Comments & Activities

  • Issue created by @prudloff
  • 🇳🇿New Zealand quietone

    Changes are made on on 11.x (our main development branch) first, and are then back ported as needed according to the Core change policies .

  • 🇬🇧United Kingdom catch

    Requiring the flag to be set could work, we'd need to deprecate not having it set first, and probably require it in Drupal 13 because there are a lot more routes out there than entity queries.

  • Merge request !11428Resolve #3508087 "Make it harder" → (Open) created by prudloff
  • Pipeline finished with Failed
    about 2 months ago
    Total: 636s
    #444016
  • Pipeline finished with Failed
    about 2 months ago
    Total: 121s
    #444023
  • 🇫🇷France prudloff Lille

    I added a runtime deprecation and a test.
    But now of course a lot of tests trigger the deprecation.

  • Pipeline finished with Failed
    about 2 months ago
    Total: 416s
    #444024
  • 🇬🇧United Kingdom longwave UK

    This does feel a bit heavy handed because the vast majority of GET requests do not require this as far as I can tell, so we're making a lot of busy work.

    Can we detect writes to config or content entities via events or hooks, and if they were triggered by an HTTP GET request, ensure that it was protected via CSRF? If there is a case where this can happen where CSRF is not required, maybe we can just ensure the route has the CSRF check flag specified, even if it's set to false?

  • 🇫🇷France prudloff Lille

    I think it would be hard to detect which routes need to be protected against CSRF.
    POST requests can also be vulnerable (but only when cookies use SameSite=None which is not recommended).
    And modifying config or content are not the only actions that need to be protected, for example a route that triggers an external API call could also be vulnerable.

  • 🇨🇭Switzerland berdir Switzerland

    We can probably identify a few more patterns that we can exclude other than just form, such as entity view and so on.

    Looking at the test fails, most have a few but many are repeating very often. If we fix a few of, e.g. system, user and entity routes them then we might get a better picture of how big the impact really is.

    Considering recent contrib security issues, I think it's worth exploring this bit. I think the entity query access change was at least as impactful. this is mostly about a single file per module and easier to identify than those entity queries.

Production build 0.71.5 2024