
Drupal 11.4.8 - 高 - リモート - XSS - Move Block の兄弟ラベルが @label エスケープをスキップする
abraxaslabs.tech · github.com/abraxas · @abraxas_null · [email protected] · drupal-move-block-markup
解説記事: https://abraxaslabs.tech/research/drupal-move-block-markup
分類: 蓄積型XSS 到達範囲: リモート
Drupal core 11.4.8 (61044508) - Drupal
SA-CORE-2026-012 により、現在の Move Block 行は t('@label (current)') に切り替えられ、これは Html::escape() されます。同じリージョン内の兄弟行は依然として BlockPluginTrait::label() を MoveBlockForm 内の #markup に直接代入しています。そのラベルは configuration['label']、すなわち生のテキストフィールドです。その後 Renderer::ensureMarkupIsSafe が管理者タグリストで文字列をXSSフィルタリングするため、<b>(およびその他の管理者タグ)が生き残ります。
ブロックタイトルをHTMLに設定できる Layout Builder 編集者が、そのリージョン内の別のブロックで Move を開く別の編集者または管理者に到達します。Move ダイアログにおける蓄積型XSSです。RCE でも LPE でもありません。
| ID | CVE 未割当 |
| 分類 | 蓄積型XSS |
| 到達範囲 | リモート(Layout Builder のブロック設定。被害者が Move Block を開く) |
| CWE | CWE-79 |
| CVSS | Medium: 5.4 CVSS:3.1/AV:N/AC:L/PR:L/UI:R/S:C/C:L/I:L/A:N |
| 製品 | Drupal core |
| 影響を受けるバージョン | 11.4.8 (61044508071749629aaf3380aa85971e94df9e84) |
| 認証 | Layout Builder のブロック設定。被害者が Move Block を開く。 |
| ライセンス | GNU Affero GPL v3.0 |
| ラボ | 127.0.0.1 のみ |
書き込み側: Layout Builder のブロックを配置または設定できるユーザー(サイト設定権限ではない)。被害者: 同じリージョン内の別のブロックで Move を開く、別の LB 編集者または管理者。
| 権限 | メソッド / シンク | 種類 | ラボ実証または推測 |
|---|---|---|---|
| Move ダイアログの兄弟行に攻撃者のHTMLを出力する | $label['#markup'] = $plugin->label(); の後に ensureMarkupIsSafe | HTMLの完全性 | ラボ実証済み。兄弟HTMLは <b class="lb-sib">DRUPAL-MOVE-BLOCK-MARKUP-WITNESS</b> |
管理者タグのマークアップ(<b> および Xss::getAdminTagList の残り)を保持する | 文字列 #markup はエスケープされず、管理者リストでXSSフィルタリングされる | HTMLの完全性 | <b> についてラボ実証済み |
| Layout Builder オリジンにおける被害者編集者としてのセッション / 操作 | そのダイアログにおける蓄積型XSS | 被害者セッションの完全性 | 推測。ラボは兄弟セル内の生HTMLで止まる |
| 否定: 現在の行 | t('@label (current)', ...) | クローズ済み | ラボ実証済み。<em class="lb-cur">... |
否定: @label 経由の兄弟 | パッチ済みガジェット経路 | クローズ済み | ラボ実証済み。<b class="lb-sib">... |
この残存項目についてクローズ済み: 稼働中の Drupal サイトインストール(このラボはガジェット);計測されたHTTPオラクルとしての Layout Builder UI セッション窃取;RCE;LPE。未認証の訪問者は Move Block を開けません。
同じピンにおける残存項目: AttributeXss HTMX attrs。
SA-CORE-2026-012 の後、Drupal 11.4.8 をピン留めしました。アドバイザリは現在のブロックタイトルをクローズしました。MoveBlockForm.php 210-218:
if ($is_current_block) {
$label['#markup'] = $this->t('@label (current)', ['@label' => $plugin->label()]);
// ...
}
else {
$label['#markup'] = $plugin->label();
}
BlockPluginTrait::label() は設定されている場合 configuration['label'] を返します。Renderer::ensureMarkupIsSafe は MarkupInterface を XSS フィルタリングしません(@label はすでにエスケープ済み)。生の文字列は管理者タグリストでフィルタリングされます。
すでに記録済みの誤った方向性:現在の行をまだ生であると扱うこと(そうではない);これを RCE だと主張すること;ライブの Drupal サイトを唯一のオラクルとすること(残っているのはこれらの関数である);リバースシェル。茶番。
python3 drupal-move-block-markup-Abraxas-Labs.py
または
cd lab
./run.sh
必ず http://127.0.0.1:19490 のみを対象とすること。11.4.8 の関数群(MoveBlockForm の残骸のコピー、FormattableMarkup、ensureMarkupIsSafe、Xss::filter)を忠実に再現したガジェットである。実際に稼働している drupal:11.4.8 サイトではない。最終行では 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
現在のブロックだけでなく、すべての行に @label(または Html::escape)を使用してください。
61044508071749629aaf3380aa85971e94df9e84)MoveBlockForm.php · BlockPluginTrait.phpGNU Affero GPL v3.0。LICENSE を参照してください。ループバックラボ専用です。保証はありません。