
Drupal 11.4.8 - Alta - Remota - XSS - AttributeXss todavía permite atributos HTMX
abraxaslabs.tech · github.com/abraxas · @abraxas_null · [email protected] · drupal-htmx-attr
Análisis: https://abraxaslabs.tech/research/drupal-htmx-attr
Clase: XSS almacenado Alcance: Remoto
Drupal core 11.4.8 (61044508) - Drupal
SA-CORE-2026-011 cerró los atributos HTMX en Xss::attributes(). Los atributos de enlaces y menús pasan por AttributeXss::sanitizeAttributes, y esa lista de omisión todavía solo descarta style y on*.
Un editor de contenido que puede establecer un campo Link (o un enlace de menú) puede almacenar hx-on-click o data-hx-on-click. Standard más BigPipe carga core/htmx. Cuando un administrador o cualquier otro visitante abre ese nodo y hace clic en el enlace, HTMX ejecuta el JS almacenado en el origen del sitio.
| ID | aún sin CVE |
| Clase | XSS almacenado (atributos de eventos HTMX) |
| Alcance | Remoto (escritor autenticado de campo Link / menú; la víctima visualiza y hace clic) |
| CWE | CWE-79 |
| CVSS | Alto: 8.7 CVSS:3.1/AV:N/AC:L/PR:L/UI:R/S:C/C:H/I:H/A:N |
| Producto | Drupal core |
| Afectado | 11.4.8 (61044508071749629aaf3380aa85971e94df9e84) |
| Autenticación | usuario autenticado que puede escribir un campo Link (o un enlace de menú). La víctima visualiza la página y hace clic. |
| Licencia | GNU Affero GPL v3.0 |
| Laboratorio | solo 127.0.0.1 |
Escritor: un editor de contenido que puede establecer options.attributes de un enlace (campo Link, enlace de menú, JSON:API). Víctima: cualquiera cuya página cargue HTMX (Standard más BigPipe carga core/htmx), incluido un administrador del sitio que haga clic en el enlace.
| Privilegio | Método / ruta | Tipo | Demostrado en laboratorio o inferido |
|---|---|---|---|
| Persistir atributos de eventos HTMX en un enlace | POST /jsonapi/node/article con field_link.options.attributes.hx-on-click y data-hx-on-click | Integridad del campo almacenado | Demostrado en laboratorio. JSON:API 201, los atributos almacenados aún contienen hx-on-click |
Imprimir esos atributos en el <a> del nodo | LinkFormatter -> AttributeXss::sanitizeAttributes | Integridad del HTML | Demostrado en laboratorio. El HTML de GET /node/1 contiene hx-on-click y el marcador window['DRUPAL-HTMX-ATTR-WITNESS']=1 |
| Ejecutar ese JS en el origen de la víctima cuando hace clic | HTMX vincula hx-on-* | Integridad de la sesión de la víctima | Inferido a partir de HTMX y de que la página carga core/htmx. El laboratorio no ejecutó un clic en navegador |
| Actuar como el visitante (cookie de sesión, clics en la interfaz de administración) | El mismo XSS almacenado | Integridad de la sesión de la víctima | Inferido. El laboratorio se detiene en el atributo que permanece en el HTML |
Negativo: Xss::filter | Xss::filter('<a ... hx-on-click=...>') | Cerrado | Demostrado cerrado en laboratorio. xss_keeps_hx=False |
| Escritura no autenticada del enlace | JSON:API sin sesión | Cerrado | El laboratorio inició sesión como uid 1 primero. Un desconocido sin cuenta no puede establecer el campo |
| RCE de PHP / LPE | n/a | Cerrado | Este remanente es JS de navegador, no PHP en el servidor |
Mismo remanente de la versión fijada: Move Block sibling markup.
Fijé drupal/drupal 11.4.8 después de SA-CORE-2026-011. Cinco búsquedas: XSS/HTMX, archivos/MIME/oEmbed, JSON:API/unserialize/SQLi, auth/CSRF/Host, REST/media/Views. El acceso a JSON:API, las claves IN de EntityQuery (SA-004), el POI de campos serializados (SA-005) y el Host de rebuild.php (SA-007) permanecen parcheados. La lista de omisión de HTMX solo se aplicó en 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 restante:
$skip = (
$attribute_name == 'style' ||
str_starts_with($attribute_name, 'on') ||
str_starts_with($attribute_name, '-') ||
strlen($attribute_name) > 96
);
Los llamadores incluyen LinkFormatter.php y MenuLinkContent::getUrlObject().
Pistas falsas ya registradas: tratar Xss::filter como el residuo (es el control); escritura JSON:API sin autenticación; RCE en PHP; una reverse shell. Teatro. El oráculo es el atributo que permanece en el HTML del nodo junto con core/htmx cargado.
python3 drupal-htmx-attr-Abraxas-Labs.py
o
cd lab
./run.sh
Dirígete solo a http://127.0.0.1:19480. drupal:11.4.8-apache en vivo, perfil Standard, escritura JSON:API habilitada para el laboratorio. Proyecto 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
Copia la lista de denegación de hx / data-hx / srcdoc en AttributeXss. Incorpórala en Xss como ya indica el docblock de la clase.
61044508071749629aaf3380aa85971e94df9e84)AttributeXss.php · Xss.phpGNU Affero GPL v3.0. Véase LICENSE. Solo laboratorio de loopback. Sin garantía.