Background information
This was originally reported as a private security issue, but has been approved for handling in the public queue by the Drupal Security Team.
- security.drupal.org private issue: https://git.drupalcode.org/security/185131-redirect-security/-/work_items/1
(included for reference. Please do not report access denied as an error.)
Problem/Motivation
This check in ajax.js can be bypassed if the URL corresponds to an existing property of the ajaxTrustedUrl object (for example .constructor) :
if (drupalSettings.ajaxTrustedUrl[originalUrl]) {
In order to exploit this an attacker would need the following permissions:
- Create redirects
- Upload files (any extension would work)
- Insert HTML with data attributes (or be able to set the URL of some existing AJAX call)
Steps to reproduce
1. Upload a .txt file containing containing this:
[{"command":"insert","method":"html","data":"<img src=x onerror=alert(0)>", "selector": "body"}]
2. Create a new redirect from /constructor to the URL of the uploaded file (for example with the redirect module).
3. Insert this HTML into a page:
<a class="use-ajax" href="constructor" data-ajax-http-method="GET">Click me</a>
4. When the link is clicked, the uploaded JSON is used as a trusted response and the JS is executed.
Proposed resolution
I suppose the easiest fix would be for core to add something like this:
drupalSettings.ajaxTrustedUrl.hasOwnProperty(originalUrl)
Remaining tasks
User interface changes
Introduced terminology
API changes
Data model changes
Release notes snippet
Issue fork drupal-3600777
Show commands
Start within a Git clone of the project using the version control instructions.
Or, if you do not have SSH keys set up on git.drupalcode.org:
Comments
Comment #5
kieran.cottI've opened an MR for this issue here - https://git.drupalcode.org/project/drupal/-/merge_requests/16061. It's similar in function to https://git.drupalcode.org/project/drupal/-/merge_requests/16060, but instead resolves the issue by use of a helper method and adds test coverage by:
I had already started working on this when MR 16060 was opened, so I've committed the work separately and will leave it to the maintainers/community to choose their preferred path forward.
Comment #6
prudloff commentedMaybe wait a bit before jumping on new issues with your LLM...
Anyway, I finished adding test coverage to my MR so now the two are very similar and we need to decide which one to keep.
Comment #7
kieran.cottHappy to keep yours - closing MR.
Comment #9
prudloff commentedComment #10
smustgrave commentedRan the test-only job since I can't in the pipeline
Was curious if failOnJavascriptConsoleErrors was needed but test fails without it failOnJavascriptConsoleErrors
Change LGTM.
Comment #14
godotislateThe new routing entries could have been attributes on the methods in the Controller class, but I don't think that's worth blocking this on. We can convert them together with the rest of the module routes in a separate issue.
Committed and pushed 2aea80d to main and 996580c to 11.x. Thanks!
This probably can go to 11.4.x as well, but will consult other committers first.
Comment #16
godotislateConsulted with @longwave on Slack, and this is good for 11.4. Committed 2ef86a5 and pushed to 11.4.x.