
Drupal 11.4.8 — высокий — удалённый — XSS — AttributeXss по-прежнему допускает HTMX-атрибуты
abraxaslabs.tech · github.com/abraxas · @abraxas_null · [email protected] · drupal-htmx-attr
Класс: Stored XSS Доступ: Удалённый
Drupal core 11.4.8 (61044508) - Drupal
SA-CORE-2026-011 закрыл HTMX-атрибуты в Xss::attributes(). Атрибуты ссылок и меню проходят через AttributeXss::sanitizeAttributes, и этот список исключений по-прежнему отбрасывает только style и on*.
Редактор контента, который может задать поле Link (или ссылку меню), может сохранить hx-on-click или data-hx-on-click. Standard плюс BigPipe загружают core/htmx. Когда администратор или любой другой посетитель открывает этот узел и кликает по ссылке, HTMX выполняет сохранённый JS в origin сайта.
| ID | CVE пока нет |
| Класс | Stored XSS (HTMX event attrs) |
| Доступ | Удалённый (аутентифицированный писатель Link field / меню; жертва просматривает и кликает) |
| CWE | CWE-79 |
| CVSS | High: 8.7 CVSS:3.1/AV:N/AC:L/PR:L/UI:R/S:C/C:H/I:H/A:N |
| Продукт | Drupal core |
| Затронуто | 11.4.8 (61044508071749629aaf3380aa85971e94df9e84) |
| Аутентификация | аутентифицированный пользователь, который может писать в поле Link (или ссылку меню). Жертва просматривает страницу и кликает. |
| Лицензия | GNU Affero GPL v3.0 |
| Лаборатория | только 127.0.0.1 |
Писатель: редактор контента, который может задать options.attributes ссылки (поле Link, ссылка меню, JSON:API). Жертва: любой, чья страница загружает HTMX (Standard + BigPipe загружают core/htmx), включая администратора сайта, который кликает по ссылке.
| Привилегия | Метод / путь | Тип | Доказано в лаборатории или выведено |
|---|---|---|---|
| Сохранить HTMX event attrs на ссылке | POST /jsonapi/node/article с field_link.options.attributes.hx-on-click и data-hx-on-click | Целостность сохранённого поля | Доказано в лаборатории. JSON:API 201, сохранённые атрибуты по-прежнему содержат hx-on-click |
Вывести эти атрибуты в <a> узла | LinkFormatter -> AttributeXss::sanitizeAttributes | Целостность HTML | Доказано в лаборатории. HTML GET /node/1 содержит hx-on-click и маркер window['DRUPAL-HTMX-ATTR-WITNESS']=1 |
| Выполнить этот JS в origin жертвы при клике | HTMX привязывает hx-on-* | Целостность сессии жертвы | Выведено из HTMX + загрузки страницей core/htmx. В лаборатории клик в браузере не выполнялся |
| Действовать от имени зрителя (session cookie, клики в admin UI) | Тот же stored XSS | Целостность сессии жертвы | Выведено. Лаборатория останавливается на сохранении атрибута в HTML |
Отрицательный: Xss::filter | Xss::filter('<a ... hx-on-click=...>') | Закрыто | Доказано закрытым в лаборатории. xss_keeps_hx=False |
| Неаутентифицированная запись ссылки | JSON:API без сессии | Закрыто | В лаборатории сначала выполнен вход как uid 1. Посторонний без аккаунта не может задать поле |
| PHP RCE / LPE | н/д | Закрыто | Этот остаток — браузерный JS, а не PHP на сервере |
Тот же остаток на этом пине: Move Block sibling markup.
Я зафиксировал drupal/drupal 11.4.8 после SA-CORE-2026-011. Пять направлений поиска: XSS/HTMX, file/MIME/oEmbed, JSON:API/unserialize/SQLi, auth/CSRF/Host, REST/media/Views. Доступ JSON:API, ключи IN в EntityQuery (SA-004), POI сериализованного поля (SA-005) и Host в rebuild.php (SA-007) остаются пропатченными. Список исключений HTMX попал только в Xss.php.
$skip = (
in_array($attribute_name, ['style', 'srcdoc']) ||
str_starts_with($attribute_name, 'on') ||
str_starts_with($attribute_name, 'data-hx') ||
str_starts_with($attribute_name, 'hx') ||
str_starts_with($attribute_name, '-') ||
strlen($attribute_name) > 96
);
Остаток в AttributeXss.php:
$skip = (
$attribute_name == 'style' ||
str_starts_with($attribute_name, 'on') ||
str_starts_with($attribute_name, '-') ||
strlen($attribute_name) > 96
);
Среди вызывающих — LinkFormatter.php и MenuLinkContent::getUrlObject().
Уже зафиксированные ложные пути: считать Xss::filter остатком (это контроль); неаутентифицированная запись через JSON:API; PHP RCE; reverse shell. Театр. Оракул — это атрибут, оставшийся в HTML узла, плюс загруженный core/htmx.
python3 drupal-htmx-attr-Abraxas-Labs.py
или
cd lab
./run.sh
Цель только http://127.0.0.1:19480. Живой drupal:11.4.8-apache, профиль Standard, запись через JSON:API включена для лаборатории. Compose-проект drupal-htmx-attr.
SUCCESS drupal-htmx-attr how=live write=jsonapi nid=1 hx-on-click=kept jsonapi-stored=1 xss-filter=stripped htmx=loaded marker=1 version=11.4.8 DRUPAL-HTMX-ATTR-WITNESS
Скопируйте denylist hx / data-hx / srcdoc в AttributeXss. Встройте его в Xss, как уже сказано в docblock класса.
61044508071749629aaf3380aa85971e94df9e84)AttributeXss.php · Xss.phpGNU Affero GPL v3.0. См. LICENSE. Только loopback-лаборатория. Без гарантий.