
Drupal 11.4.8 - Élevé - À distance - XSS - Les étiquettes des blocs frères de Move Block ignorent l'échappement @label
abraxaslabs.tech · github.com/abraxas · @abraxas_null · [email protected] · drupal-move-block-markup
Classe : XSS stocké Portée : Distant
Drupal core 11.4.8 (61044508) - Drupal
SA-CORE-2026-012 a fait passer la ligne actuelle de Move Block à t('@label (current)'), que Html::escape() échappe. Les lignes voisines dans la même région assignent toujours BlockPluginTrait::label() directement à #markup dans MoveBlockForm. Ce label est configuration['label'], un champ texte brut. Renderer::ensureMarkupIsSafe applique ensuite un filtre XSS à une chaîne avec la liste des balises admin, donc un <b> (et d'autres balises admin) survit.
Un éditeur Layout Builder qui peut définir le titre d'un bloc avec du HTML atteint un autre éditeur ou administrateur qui ouvre Move sur un autre bloc de cette région. XSS stocké dans la boîte de dialogue Move. Pas de RCE ni de LPE.
| ID | pas encore de CVE |
| Classe | XSS stocké |
| Portée | Distante (configuration de bloc Layout Builder ; la victime ouvre Move Block) |
| CWE | CWE-79 |
| CVSS | Moyen : 5.4 CVSS:3.1/AV:N/AC:L/PR:L/UI:R/S:C/C:L/I:L/A:N |
| Produit | Drupal core |
| Affecté | 11.4.8 (61044508071749629aaf3380aa85971e94df9e84) |
| Auth | Configuration de bloc Layout Builder. La victime ouvre Move Block. |
| Licence | GNU Affero GPL v3.0 |
| Lab | 127.0.0.1 uniquement |
Auteur : utilisateur qui peut placer ou configurer des blocs Layout Builder (pas la configuration du site). Victime : un autre éditeur LB ou administrateur qui ouvre Move sur un bloc différent de la même région.
| Privilège | Méthode / sink | Type | Prouvé en lab ou déduit |
|---|---|---|---|
| Afficher le HTML de l'attaquant dans la ligne voisine de la boîte de dialogue Move | $label['#markup'] = $plugin->label(); puis ensureMarkupIsSafe | Intégrité du HTML | Prouvé en lab. Le HTML voisin est <b class="lb-sib">DRUPAL-MOVE-BLOCK-MARKUP-WITNESS</b> |
Conserver le balisage des balises admin (<b>, et le reste de Xss::getAdminTagList) | la chaîne #markup est filtrée XSS avec la liste admin, pas échappée | Intégrité du HTML | Prouvé en lab pour <b> |
| Session / actions en tant qu'éditeur victime dans l'origine Layout Builder | XSS stocké dans cette boîte de dialogue | Intégrité de la session victime | Déduit. Le lab s'arrête au HTML brut dans la cellule voisine |
| Négatif : ligne actuelle | t('@label (current)', ...) | Fermé | Prouvé en lab. <em class="lb-cur">... |
Négatif : voisin via @label | chemin du gadget corrigé | Fermé | Prouvé en lab. <b class="lb-sib">... |
Fermé sur ce reliquat : installation d'un site Drupal en production (ce lab est un gadget) ; vol de session de l'interface Layout Builder comme oracle HTTP mesuré ; RCE ; LPE. Les visiteurs non authentifiés ne peuvent pas ouvrir Move Block.
Même reliquat de version : AttributeXss HTMX attrs.
J'ai épinglé Drupal 11.4.8 après SA-CORE-2026-012. L'avis a fermé le titre du bloc actuel. MoveBlockForm.php 210-218 :
if ($is_current_block) {
$label['#markup'] = $this->t('@label (current)', ['@label' => $plugin->label()]);
// ...
}
else {
$label['#markup'] = $plugin->label();
}
BlockPluginTrait::label() renvoie configuration['label'] lorsqu'il est défini. Renderer::ensureMarkupIsSafe ne filtre pas XSS MarkupInterface (@label est déjà échappé). Une chaîne brute est filtrée avec la liste des balises admin.
Fausses pistes déjà consignées : considérer la ligne actuelle comme encore brute (ce n'est pas le cas) ; prétendre qu'il s'agit d'un RCE ; un site Drupal en production comme seul oracle (le reliquat, ce sont ces fonctions) ; un reverse shell. Du théâtre.
python3 drupal-move-block-markup-Abraxas-Labs.py
ou
cd lab
./run.sh
Cible uniquement http://127.0.0.1:19490. Gadget fidèle des fonctions 11.4.8 (copie du reliquat de MoveBlockForm, FormattableMarkup, ensureMarkupIsSafe, Xss::filter). Pas un site drupal:11.4.8 en production. La dernière ligne utilise 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
Utiliser @label (ou Html::escape) pour chaque ligne, pas seulement le bloc actuel.
61044508071749629aaf3380aa85971e94df9e84)MoveBlockForm.php · BlockPluginTrait.phpGNU Affero GPL v3.0. Voir LICENSE. Lab en boucle locale uniquement. Aucune garantie.