
Drupal 11.4.8 — высокий — удалённый — XSS — AttributeXss по-прежнему допускает HTMX-атрибуты
abraxaslabs.tech · github.com/abraxas · @abraxas_null · [email protected] · drupal-htmx-attr
Разбор: https://abraxaslabs.tech/research/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. Стандартная тема вместе с BigPipe загружает core/htmx. Когда администратор или любой другой посетитель открывает этот материал и кликает по ссылке, HTMX выполняет сохранённый JS в origin сайта.
| ID | CVE пока нет |
| Класс | Stored XSS (атрибуты событий HTMX) |
| Доступ | Удалённый (аутентифицированный пользователь, пишущий в поле Link / ссылку меню; жертва просматривает и кликает) |
| CWE | CWE-79 |
| CVSS | Высокий: 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 на ссылке | 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 на странице. В лаборатории клик в браузере не воспроизводился |
| Действовать от имени посетителя (cookie сессии, клики в админ-интерфейсе) | Тот же 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, файлы/MIME/oEmbed, JSON:API/unserialize/SQLi, аутентификация/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; обратная оболочка. Театр. Оракулом является атрибут, остающийся на 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
Скопируйте денилист hx / data-hx / srcdoc в AttributeXss. Включите его в Xss, как уже указано в docblock класса.
61044508071749629aaf3380aa85971e94df9e84)AttributeXss.php · Xss.phpGNU Affero GPL v3.0. См. LICENSE. Только для loopback-лаборатории. Без гарантий.