Broken redirect from RouteNormalizerRequestSubscriber when ajax_page_state present and $request->overrideGlobals() has been called

Created on 10 March 2024, about 1 year ago

Problem/Motivation

Originally reported to Cloudflare module in 🐛 AJAX calls break on Drupal 10.2 when using restore client ip + redirect module RTBC but cross posted relevant details here in case it is appropriate to solve here.

RouteNormalizerRequestSubscriber uses $request->server->get('QUERY_STRING') as part of a comparison to determine if a route should be normalized.

I note a comment in the file around why $request->query->all() is not used

// Don't pass in the query here using $request->query->all()
// since that can potentially modify the query parameters.

However $request->server->get('QUERY_STRING') is also not immutable - if anything prior calls $request->overrideGlobals() then any query parameters modified are also present here.

This is an issue in 10.2 as after Libraries item in AJAX page state is compressed the query will contain the uncompressed libraries - so if anything has called $request->overrideGlobals() after the AjaxPageState middleware then the QUERY_STRING param will have the uncompressed libraries here - and redirect module will use this to redirect to a URL with the uncompressed url params - which breaks the page as the libraries can not be parsed in the following request as the URL param is no longer compressed.

Steps to reproduce

  1. Add code that is executed after AjaxPageState middleware and before RouteNormalizerRequestSubscriber that calls overrideGlobals on the request*
  2. Add ajax to any view
  3. Observe ajax is broken as ajax page state can not be parsed

* Currently from a search it looks like cloudflare and reverse_proxy_header call overrideGlobals - it may be present elsewhere and with other combinations of modified parameters.

Proposed resolution

It is possible to get the original query string via parse_url($request->getRequestUri(), PHP_URL_QUERY) - its not immediately clear from the Symfony code if this is intentionally immutable or why overrideGlobals modifies some server params and not others.

Remaining tasks

  1. Decide if this issue should be resolved by modifying RouteNormalizerRequestSubscriber
  2. Replace usage of $request->server->get('QUERY_STRING') with parse_url($request->getRequestUri(), PHP_URL_QUERY)
  3. Add test coverage for modified query params and overrideGlobals

User interface changes

API changes

Data model changes

🐛 Bug report
Status

Active

Version

1.0

Component

Code

Created by

🇳🇿New Zealand ericgsmith

Live updates comments and jobs are added and updated live.
Sign in to follow issues

Merge Requests

Comments & Activities

Production build 0.71.5 2024