Issue #3600777: Fix AJAX trusted URL inherited property bypass
Summary
This fixes AJAX trusted URL checks so inherited JavaScript object properties, such as constructor, are not treated as trusted AJAX URLs.
Problem
core/misc/ajax.js checked trusted AJAX URLs with direct property access: drupalSettings.ajaxTrustedUrl[url].
This also resolves inherited properties from Object.prototype. A URL such as constructor can therefore evaluate truthy even when it was never added to drupalSettings.ajaxTrustedUrl.
If an attacker can cause a use-ajax link to point at such a path and redirect that request to attacker-controlled JSON, Drupal can incorrectly treat the response as trusted and process AJAX commands without the X-Drupal-Ajax-Token header.
Changes
- Added a shared
isAjaxTrustedUrl()helper usingObject.prototype.hasOwnProperty.call(). - Updated all AJAX trusted URL checks in
core/misc/ajax.jsto use own-property checks. - Added an
ajax_testregression page with ause-ajaxlink to constructor. - Added an untrusted JSON response route that returns an AJAX insert command without the verification header.
- Added a functional JavaScript regression test asserting the untrusted response is rejected and not processed.
Test Coverage
Added:
Drupal\FunctionalJavascriptTests\Ajax\AjaxTest::testAjaxTrustedUrlInheritedProperty()
The test reproduces the inherited property bypass using constructor and verifies that the untrusted AJAX response is blocked.
Closes #3600777