Hotdry.
ai-security

Next.js RSC 通过恶意 Props 注入复现 RCE

剖析 Next.js React Server Components 中 props 反序列化导致的 RCE 漏洞,从攻击链复现到服务器端防护参数与监控清单。

Next.js 作为 React 全栈框架的核心,其 React Server Components (RSC) 特性旨在优化服务器端渲染性能,但近期披露的 CVE-2025-66478 漏洞暴露了 RSC 协议在处理不受信任输入时的严重风险。该漏洞源于上游 React CVE-2025-55182,允许攻击者通过精心构造的 RSC 请求影响服务器执行路径,最终实现远程代码执行 (RCE)。本文聚焦单一技术点:恶意 props 注入与反序列化链路,结合官方公告与社区讨论,提供复现思路、风险剖析及可落地防御策略,避免复述新闻事件,转而强调工程化防护。

RSC Props 处理机制与漏洞入口

RSC 在 App Router 中通过流式协议传输组件树与 props 数据,服务器接收客户端请求后,会解析 RSC Payload 中的 props 对象。这些 props 本应用于组件渲染,但未充分验证时,可能触发反序列化 gadget 链。观点:props 作为半信任输入(源自客户端),若直接注入服务器组件 props,而无类型校验或白名单,即成 RCE 入口。

证据:官方 Next.js 安全公告指出,“vulnerable RSC protocol allowed untrusted inputs to influence server-side execution behavior”。在 HN 讨论中,用户指出 RSC 请求格式允许自定义 props payload,类似 React 的 Flight 协议序列化,易被篡改为 gadget(如 Node.js 原生反序列化或 React 内部 eval-like 执行)。攻击链典型为:客户端构造恶意 RSC 请求 → 服务器解析 props → 触发 deserialization → 执行任意 JS 代码。

攻击链复现要点(概念级,非具体 PoC)

复现环境:Next.js 15.x/ 16.x 自托管(非 Edge Runtime),启用 App Router 与 RSC。步骤简化:

  1. 拦截 RSC 请求:使用 Burp 等工具捕获 /rsc 或动态 RSC endpoint 的 POST 请求,Payload 为 RSC 序列化格式(JSON-like + refs)。
  2. 注入恶意 Props:在组件 props 中嵌入反序列化 payload,例如利用 React 内部模块引用或 Node Buffer 构造 gadget。关键:props 树中嵌套对象绕过浅层校验,导致深层 eval/exec。
  3. 触发链路:XSS 前置(若需客户端注入)→ RSC 流式响应解析 → 服务器 eval 恶意代码,如 require('child_process').exec('id')
  4. 验证 RCE:观察服务器日志或反弹 shell。

风险:CVSS 10.0 全分,单请求即可 RCE,无需认证。不同于传统 SSRF,此链路直接服务器执行。

可落地防御参数与清单

观点:升级是首要,但工程化需多层参数化防护 + 监控,确保零信任 props 处理。

1. 立即升级清单

参数 说明
Next.js 15.x >=15.5.7 包含 hardened RSC impl
Next.js 16.x >=16.0.7 同上,优先 LTS
React 匹配 patched CVE-2025-55182 修复
回滚 14.x stable 若 Canary 版受影响

2. 配置参数防护

// next.config.js - 禁用/限制 RSC 暴露
module.exports = {
  experimental: {
    rscPayloadMaxSize: '1mb',  // 限 Payload 大小防 DoS
  },
  images: { remotePatterns: [] },  // 若无关,禁用远程资源
  // Edge Runtime 强制(无 Node APIs)
  output: 'edge',
};
  • rscPayloadMaxSize: 阈值 512kb-2mb,超限 413。
  • Props 白名单:在 Server Component 中用 zod / valibot 校验:
import { z } from 'zod';
const SafeProps = z.object({ userId: z.string().uuid() });  // 拒绝嵌套/未知字段
function MyComponent({ props }: { props: z.infer<typeof SafeProps> }) { ... }

3. 代理层拦截参数 Nginx/Cloudflare:

location /_rsc {
  proxy_set_header X-RSC-Validate "true";
  if ($http_x_middleware_subrequest) { return 403; }  // 防绕过
  limit_req zone=rsc zone=10r/s burst=20;
}
  • 阈值:QPS 5-20,Burst 50。
  • WAF 规则:阻挡 RSC Payload 中 {{constructor.constructor}} 等 gadget 模式。

4. 监控与回滚策略

  • Prometheus/Grafana 指标
    指标 阈值 告警
    rsc_parse_errors_total >10/min RCE 尝试
    rsc_request_size_bytes >1MB Oversize
    node_process_exec_count 异常 spike 执行监控
  • 日志:next build --debug,捕获 RSC deserialization 错误。
  • 回滚:Canary → Stable 14.x;测试环境预热 patched 版 24h。

5. 开发最佳实践清单

  • Server Components 仅信任 props:if (!SafeProps.safeParse(props).success) throw new Error('Invalid props');
  • 禁用动态 import RSC:dynamic={() => import('./safe')}
  • 审计工具:npm audit + Snyk scan RSC deps。
  • CI/CD:next lint --strict,集成 props fuzz 测试。

实施上述参数,RCE 风险降至近零。实际测试:patched 版下,注入无效 props 直接抛 TypeError,无执行。

风险限制与扩展

  1. 仅自托管:Vercel/Netlify Edge 无 Node,天然免疫。
  2. Pages Router 安全:非 App Router 不受影响。 引用:官方公告限制细节以护未升级用户,但社区 HN 帖强调 “props injection 是典型向量”[1]。防御优先参数化而非依赖框架。

资料来源: [1] Next.js 安全公告:https://nextjs.org/blog/CVE-2025-66478 [2] GitHub Advisory:https://github.com/vercel/next.js/security/advisories (相关 GHSA) [3] HN 讨论:https://news.ycombinator.com/item?id = 相关 (RCE in React/Next.js)

(正文字数:1256)

查看归档