
Drupal 11.4.8 - Alta - Remota - XSS - Move Block sibling labels skip @label escaping
abraxaslabs.tech · github.com/abraxas · @abraxas_null · [email protected] · drupal-move-block-markup
Clase: XSS Almacenado Alcance: Remoto
Drupal core 11.4.8 (61044508) - Drupal
SA-CORE-2026-012 cambió la fila actual de Move Block a t('@label (current)'), que aplica Html::escape(). Las filas hermanas en la misma región todavía asignan BlockPluginTrait::label() directamente a #markup en MoveBlockForm. Ese label es configuration['label'], un campo de texto sin procesar. Renderer::ensureMarkupIsSafe luego filtra XSS sobre una cadena con la lista de etiquetas de administrador, por lo que un <b> (y otras etiquetas de administrador) sobrevive.
Un editor de Layout Builder que puede establecer el título de un bloque con HTML alcanza a otro editor o administrador que abre Move en un bloque diferente de esa región. XSS Almacenado en el diálogo Move. No es RCE ni LPE.
| ID | aún sin CVE |
| Clase | XSS Almacenado |
| Alcance | Remoto (configuración de bloque de Layout Builder; la víctima abre Move Block) |
| CWE | CWE-79 |
| CVSS | Medio: 5.4 CVSS:3.1/AV:N/AC:L/PR:L/UI:R/S:C/C:L/I:L/A:N |
| Producto | Drupal core |
| Afectado | 11.4.8 (61044508071749629aaf3380aa85971e94df9e84) |
| Autenticación | Configuración de bloque de Layout Builder. La víctima abre Move Block. |
| Licencia | GNU Affero GPL v3.0 |
| Laboratorio | solo 127.0.0.1 |
Escritor: usuario que puede colocar o configurar bloques de Layout Builder (no configuración del sitio). Víctima: otro editor de LB o administrador que abre Move en un bloque diferente de la misma región.
| Privilegio | Método / sink | Tipo | Probado en laboratorio o inferido |
|---|---|---|---|
| Imprimir HTML del atacante en la fila hermana del diálogo Move | $label['#markup'] = $plugin->label(); luego ensureMarkupIsSafe | Integridad del HTML | Probado en laboratorio. El HTML hermano es <b class="lb-sib">DRUPAL-MOVE-BLOCK-MARKUP-WITNESS</b> |
Mantener el marcado de etiquetas de administrador (<b>, y el resto de Xss::getAdminTagList) | la cadena #markup se filtra por XSS con la lista de administrador, no se escapa | Integridad del HTML | Probado en laboratorio para <b> |
| Sesión / acciones como el editor víctima en el origen de Layout Builder | XSS Almacenado en ese diálogo | Integridad de la sesión de la víctima | Inferido. El laboratorio se detiene en HTML sin procesar en la celda hermana |
| Negativo: fila actual | t('@label (current)', ...) | Cerrado | Probado en laboratorio. <em class="lb-cur">... |
Negativo: hermana a través de @label | ruta del gadget parcheado | Cerrado | Probado en laboratorio. <b class="lb-sib">... |
Cerrado sobre este remanente: instalación de sitio Drupal en vivo (este laboratorio es un gadget); robo de sesión de la interfaz de Layout Builder como oráculo HTTP medido; RCE; LPE. Los visitantes no autenticados no pueden abrir Move Block.
Mismo pin remanente: AttributeXss HTMX attrs.
Fijé Drupal 11.4.8 después de SA-CORE-2026-012. El aviso cerró el título del bloque actual. MoveBlockForm.php 210-218:
if ($is_current_block) {
$label['#markup'] = $this->t('@label (current)', ['@label' => $plugin->label()]);
// ...
}
else {
$label['#markup'] = $plugin->label();
}
BlockPluginTrait::label() devuelve configuration['label'] cuando está establecido. Renderer::ensureMarkupIsSafe no filtra XSS sobre MarkupInterface (@label ya está escapado). Una cadena sin procesar se filtra con la lista de etiquetas de administrador.
Caminos equivocados ya registrados: tratar la fila actual como todavía sin procesar (no lo es); afirmar que esto es RCE; un sitio Drupal en vivo como único oráculo (el remanente son estas funciones); una reverse shell. Teatro.
python3 drupal-move-block-markup-Abraxas-Labs.py
o
cd lab
./run.sh
Objetivo solo http://127.0.0.1:19490. Gadget fiel de las funciones de 11.4.8 (copia del remanente de MoveBlockForm, FormattableMarkup, ensureMarkupIsSafe, Xss::filter). No es un sitio drupal:11.4.8 en vivo. La última línea usa how=gadget.
SUCCESS drupal-move-block-markup how=gadget sibling-raw-tag=yes current-escaped=yes patched-sibling-escaped=yes DRUPAL-MOVE-BLOCK-MARKUP-WITNESS
Usar @label (o Html::escape) para cada fila, no solo para el bloque actual.
61044508071749629aaf3380aa85971e94df9e84)MoveBlockForm.php · BlockPluginTrait.phpGNU Affero GPL v3.0. Ver LICENSE. Solo laboratorio en loopback. Sin garantía.