
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 행을 Html::escape()를 수행하는 t('@label (current)')로 변경했습니다. 같은 영역의 형제 행들은 여전히 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 | 중간: 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(@label은 이미 이스케이프됨)를 XSS 필터링하지 않습니다. 원시 문자열은 관리자 태그 목록으로 필터링됩니다.
이미 기록된 잘못된 방향: 현재 행을 여전히 원시 상태로 취급하는 것(그렇지 않음); 이것이 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를 참조하세요. 루프백 실험실 전용입니다. 보증은 제공되지 않습니다.