"nojs"/"ajax" route parameter in use-ajax link breaks CSRF protection

Created on 17 February 2016, almost 9 years ago
Updated 20 March 2023, almost 2 years ago

Problem/Motivation

When creating a route that makes use of the nojs functionality of Drupal Ajax (the one that replaces "nojs" with "ajax" in your link when the link has the "use-ajax" class) in combination with the "_csrf_token" requirement on your route, the CSRF validation breaks on ajax requests as the path doesn't match the original rendered path anymore for which the token was generated.

For example:
My original link is:
/flag/flag/bookmark/1/nojs?destination=node/1&token=BKjZye8PPzpXvn_VlslxaXv_XdT1KoD5e-mGeaRmMlk
Drupal changes this path into:
/flag/flag/bookmark/1/ajax?destination=node/1&token=BKjZye8PPzpXvn_VlslxaXv_XdT1KoD5e-mGeaRmMlk

The new URL makes us able to return a proper response if the user has JS disabled (or just opened the link in a new tab).
However, "_csrf_token" bases it's token on the generated path, including all parameters, so when requested Ajax URL get's validated with \Drupal\Core\Access\CsrfAccessCheck, it denies access.

Proposed resolution

How I'm seeing it there are 2 possible solutions:

  • We use a predefined parameter for such URLs, maybe {js}? Example: "/flag/flag/{flag}/{entity_id}/{js}". That parameter is replaced inside \Drupal\Core\Access\CsrfAccessCheck and \Drupal\Core\Access\RouteProcessorCsrf to always contain the same value, so that CSRF thinks our path always is /flag/flag/{flag}/{entity_id}/js
  • We move the nojs/ajax from the path to the query string.
πŸ› Bug report
Status

Needs work

Version

10.1 ✨

Component
AjaxΒ  β†’

Last updated 3 days ago

Created by

πŸ‡³πŸ‡±Netherlands jeroen.b

Live updates comments and jobs are added and updated live.
  • Contributed project blocker

    It denotes an issue that prevents porting of a contributed project to the stable version of Drupal due to missing APIs, regressions, and so on.

  • Needs change record

    A change record needs to be drafted before an issue is committed. Note: Change records used to be called change notifications.

  • Needs release note

    The major change should have a special release note written to summarize the importance of the change. See Write a release note for an issue.

  • Needs issue summary update

    Issue summaries save everyone time if they are kept up-to-date. See Update issue summary task instructions.

Sign in to follow issues

Comments & Activities

Not all content is available!

It's likely this issue predates Contrib.social: some issue and comment data are missing.

  • πŸ‡«πŸ‡·France izus

    confirmig #50 did it for me.
    Thank you

  • πŸ‡¬πŸ‡§United Kingdom joachim

    Couple of things:

    1. +++ b/core/lib/Drupal/Core/Access/RouteProcessorCsrfAjax.php
      @@ -0,0 +1,73 @@
      + * Processes outbound ajax/nojs route to handle the CSRF token.
      

      This needs documentation to explain why this class is different from the parent.

    2. +++ b/core/lib/Drupal/Core/Access/RouteProcessorCsrfAjax.php
      @@ -0,0 +1,73 @@
      +  public function processOutbound($route_name, Route $route, array &$parameters, BubbleableMetadata $bubbleable_metadata = NULL) {
      

      This method looks the same as in the parent?

Production build 0.71.5 2024