技术深度剖析:React Server Components 的工作原理及漏洞出现位置

发布: (2025年12月16日 GMT+8 04:42)
6 min read
原文: Dev.to

Source: Dev.to

一个简化但准确的 RSC 请求生命周期如下:

  1. 传入请求到达 RSC 端点

    • 在 Next.js 中,这通常映射到内部路由,例如 /_rsc
    • 请求在身份验证和应用中间件之前被处理。
  2. 请求体解析和协议解码

    • 按照 React Flight 协议解析负载。
    • 这包括解码序列化的组件引用、props 和执行提示。
    • 在此阶段,React 假设负载的结构足够有效以继续处理。
  3. 组件图重建

    • React 从序列化的输入中重建服务器组件树。
    • 模块引用被解析并加载。
    • 异步边界和 Suspense 段被注册。
  4. 服务器渲染与流式传输

    • 组件在服务器上执行。
    • 输出再次序列化并以块的形式流回客户端。
    • 错误边界和部分结果会增量刷新。
  5. 错误与恢复

    • 如果在流式传输过程中出现异常,React 会尝试优雅恢复。
    • 元数据、堆栈跟踪和模块标识符仍然在内部可用。
    • 这些阶段都对格式错误或恶意输入高度敏感。

拒绝服务(DoS)是如何触发的

DoS 问题主要出现在第 2 步和第 3 步,在任何应用逻辑介入之前。

恶意请求可以:

  • 膨胀序列化负载的大小。
  • 引入深度嵌套或循环引用。
  • 强制过度的异步边界解析。

概念示例(JSON 负载):

POST /_rsc
Content-Type: application/json

{
  "type": "ServerComponent",
  "props": {
    "children": {
      "children": {
        "children": {
          "...": "..."
        }
      }
    }
  }
}

即使负载在语法上是有效的,React 也会:

  • 尝试反序列化它。
  • 构建内存中的组件图。
  • 调度执行和流式工作。

这会导致:

  • 解码期间 CPU 使用率飙升。
  • 图重建期间内存压力增大。
  • 工作线程或事件循环饱和。

关键是,这一切发生在不触及用户自定义代码且不经过身份验证的情况下,使得传统的应用层防御假设基本失效。

源代码泄露是如何产生的

源代码泄露是 React 在第 4 步和第 5 步处理错误时的副作用。

当渲染或序列化错误在流式传输中途发生时:

  • React 仍然持有内部模块路径的引用。
  • 堆栈跟踪中包含已解析的文件位置。
  • 组件元数据会部分序列化。

在某些边缘情况,这些信息可能:

  • 泄漏到流式响应中。
  • 出现在错误负载里。
  • 在流被正确中止前被刷新出来。

泄漏信息示例(JavaScript 错误):

Error: Failed to resolve Server Component
  at /app/src/components/admin/UserList.server.tsx
  at react-server-dom-webpack/server

这会暴露:

  • 项目目录结构。
  • 仅服务器可用的组件边界。
  • 内部模块布局和命名。

虽然这本身不是独立的利用手段,但会显著降低针对性攻击的准备成本。

为什么不需要 Server Actions

一个常见的误解是这些风险仅在使用 Server Actions 时才会出现。实际上:

  • Server Actions 只是一个 API 表面。
  • RSC 是运行时和协议。

即使是一个简单的页面:

export default async function Page() {
  return ;
}

仍然会触发:

  • 请求反序列化。
  • 组件图重建。
  • 服务器执行与流式传输。

易受攻击的逻辑会在不定义 Server Actions 的情况下执行。

关键要点

  • React Server Components 引入了一种根本性的服务器端执行模型,它将请求反序列化、组件图重建以及基于流的渲染合并为单一的框架管理流水线。
  • 有效的攻击面存在于 身份验证之前应用中间件之前、以及 任何用户自定义业务逻辑执行之前
  • 格式错误或对抗性的 RSC 请求可能导致:
    • 拒绝服务:在反序列化和组件图重建期间导致 CPU 过度使用、内存压力以及工作线程或事件循环饱和。
    • 意外泄露服务器实现细节:包括内部文件路径、组件边界和模块布局,作为流式错误处理的副作用。
  • 这些问题并非由配置错误的应用或不安全的用户代码引起;它们是 React Server Components 运行时本身的框架级漏洞,单靠应用层防御难以可靠缓解。

官方通告与补丁

Back to Blog

相关文章

阅读更多 »