我们的 AI 引擎 Neutron 在加州大学伯克利分校的 CyberGym 基准测试中取得了 97.1% 的成绩。 了解更多

深度解析

深度解析

GHSA-673q-mjm6-r5xr:Next.js “use cache”函数中的未授权 RCE

GitHub Advisory Database 将 GHSA-673q-mjm6-r5xr 评为严重,CVSS v4.0 9.5:未经身份验证的攻击者可在使用 App Router、启用 Cache Components 且有 use cache 函数返回多个类型化数组的 Next.js 16 服务器上执行代码。数据库评审将其分类为 Next.js 捆绑的 React Server Components 传输协议中对不可信数据的反序列化(CWE-502)。Next.js 16.4.1 已修复,没有临时措施。

要点速览

  • 未经身份验证的攻击者可在启用 Cache Components 且有 use cache 函数返回多个类型化数组的 Next.js 16 应用上实现远程代码执行。GitHub Advisory Database 评审将其分类为 CWE-502,即不可信数据反序列化。
  • Next.js 16 的 16.0.0 至 16.4.0 所有版本均受影响。GitHub Advisory Database 将其评为严重,CVSS v4.0 9.5,可通过网络利用,无需身份验证或用户交互。
  • 没有公开概念验证,截至 2026 年 10 月 23 日没有已知在野利用,问题未列入 CISA 已知被利用漏洞目录。
  • 立即升级至 Next.js 16.4.1。Vercel 表示没有临时措施,即使应用没有返回类型化数组的 use cache 函数,也建议立即升级。

我是否受到影响?

如果应用运行 Next.js 16.0.0 至 16.4.0,使用 App Router 且启用了 Cache Components,就会受到影响。Cache Components 是 Next.js 16 的缓存模型,标记为 use cache 的函数会跨请求存储和恢复结果。公告中的触发条件是某个 use cache 函数返回多个类型化数组,例如 Uint8Array 或 Float64Array 值。

分支 受影响版本 修复版本
Next.js 16.x 16.0.0 – 16.4.0 16.4.1

检查已安装版本:

# Installed Next.js version
npm ls next
node -e "console.log(require('next/package.json').version)"

# Lock file check (package-lock.json v2/v3 records the package under "node_modules/next")
grep -A1 '"node_modules/next"' package-lock.json

# Container image check
docker run --rm <your-image> node -e "console.log(require('next/package.json').version)"

然后检查代码是否启用了受影响功能。Cache Components 需要显式配置启用,use cache 则直接出现在服务端代码中:

# Cache Components enabled in the Next.js config
grep -n "cacheComponents" next.config.*

# Any use of the cache directive across the project, including src/ and shared libraries
grep -rn "use cache" --include="*.tsx" --include="*.ts" --include="*.jsx" --include="*.js" --exclude-dir=node_modules --exclude-dir=.next .

只要有一个函数返回两个或更多类型化数组,就符合已发布的触发条件。

如何修复?

将 Next.js 升级至 16.4.1 或更高版本:

npm install next@16.4.1
# or: pnpm add next@16.4.1   |   yarn add next@16.4.1

没有临时措施。Vercel 公告明确要求立即升级,即使应用没有此类 use cache 函数。同一版本还修复了同日发布的未经身份验证的 Image Optimization RCE(GHSA-2464-fhr4-w9xw,根因是上游 librsvg 漏洞 CVE-2026-96889),因此一次升级可解决两者。

根本原因是什么?

Next.js 基于 React Server Components(RSC)运行,服务器将组件输出渲染为序列化分块流,通常称为 flight 数据。重新读取该数据流就是反序列化:运行时遍历分块、解析引用,并重建对象、Promise、流、类型化数组和服务器函数引用。在 Cache Components 下,use cache 函数的返回值通过同一传输协议存储和恢复,因此反序列化器会处理源自缓存条目的数据。公告将漏洞分类为 CWE-502,即不可信数据反序列化。

Vercel 未发布精确利用路径,因此以下分析来自对修复的阅读。补丁提交 a4cea6a 的标题为“改进 Server Component 传输协议”,在全部十二种构建变体中替换捆绑的 react-server-dom-webpack 和 react-server-dom-turbopack 运行时,从四处加固反序列化边界。

首先,旧反序列化器解析每个模型条目时,不检查名为 then 的属性是否会让普通对象看起来像 Promise。JavaScript 将拥有可调用 then 属性的对象视为 Promise(thenable);对该对象执行 await 或链式操作的代码会调用此函数。新代码在解析阶段拒绝这种混淆:

// after the fix, in the bundled react-server-dom client and server runtimes
function createModel(response, model, parentObject, key) {
  return "then" === key && "function" === typeof model ? null : model;
}

修复前,createModel 原样返回模型,因此携带 then 函数的反序列化对象会保留在重建对象图中,只要运行时或应用代码将其当作 Promise,就可能调用它。

其次,服务器引用解析会将序列化引用映射到真实服务器函数,最终可能通过 requireModule 加载代码;现在该流程会验证输入:

function loadServerReference(response, metaData, parentObject, key) {
  if ("then" === key) return null;
  var id = metaData.id;
  if ("string" !== typeof id) return null;
  ...

修复前,metaData.id 未经类型检查就到达 resolveServerReference 和 requireModule。

第三,运行时不再通过分块图暴露内部响应对象。旧代码在每个已解析模型分块中,将实时响应对象直接存储为 chunk.reason;遍历重建对象的属性就可到达它,并进一步触及反序列化机制。新代码将响应藏在持有对象中、以运行时生成的 Symbol 为键,使普通属性遍历无法到达:

// before: new ReactPromise("resolved_model", value, response)
// after:
var RESPONSE_SYMBOL = Symbol();
function createResolvedModelChunk(response, value) {
  var holder = {};
  return new ReactPromise("resolved_model", value,
    ((holder[RESPONSE_SYMBOL] = response), holder));
}

第四,传输协议现在分离了此前共享同一键空间的内容。序列化载荷以表单数据条目传输,键由前缀和分块 ID 构成。各项改动分别如下:

  • 旧反序列化器通过对所有条目的原始查询解析内部状态:response._formData.data.get(response._prefix + id);类型化数组读取也通过 response._formData.data.get(key).arrayBuffer() 执行同样操作。
  • 新代码在条目到达时按种类分组:流分块的键以字段前缀加“S”开头,字符串分块和二进制 Blob 分别存入自己的映射,类型化数组通过 getBackingBlob(response._formData, key) 读取。
  • 序列化侧,客户端将流条目写在 formFieldPrefix + "S" + streamId 下,而不是原先的 formFieldPrefix + streamId。
  • 对大于 4096 字节的类型化数组(浏览器构建为 2048 字节),如果视图不从底层缓冲区起始处开始、未覆盖整个缓冲区,或缓冲区可调整大小,序列化时会复制该数组。

一句话概括:反序列化器信任读回条目的结构,接受伪装为 Promise 的对象、标识符类型任意的服务器引用,以及仅凭所带键决定种类的条目;补丁在每个信任点增加了类型和种类检查。

如何利用?

没有公开概念验证,Vercel 也未记录精确请求路径,因此以下描述的是公告和补丁所指的利用类别,而非逐步操作配方。

  1. 应用启用 Cache Components,并定义一个返回多个类型化数组的 use cache 函数。每个类型化数组成为序列化载荷中独立的二进制分块,这正是 Vercel 明确列出的必要条件。
  2. 未经身份验证的请求到达应用。CVSS 向量(网络、无需权限、无需用户交互)和 CWE-502 分类描述了攻击面:攻击者输入到达 flight 反序列化器处理的数据。
  3. 在这些数据中,攻击者提供针对补丁封堵的信任缺口构造的条目:带 then 函数、会被运行时作为 Promise 调用的对象;或 id 不是字符串却能解析为攻击者所选内容的服务器引用;或借助扁平键空间、被反序列化器当作内部分块的条目。
  4. 反序列化器解析特制条目。通过服务器引用解析,路径可以到达 requireModule,该函数将序列化引用映射到真实服务器代码。
  5. 攻击者选择的引用以 Next.js 服务器进程权限执行,实现远程代码执行。

类型化数组条件与此路径直接吻合:修复的序列化部分纠正了视图未覆盖完整底层缓冲区时的数组输出方式,反序列化部分则改变底层 Blob 的查找方式;多个类型化数组共享一个载荷时,运行的正是这些代码。

攻击流程

flowchart LR A["向 Cache Components 路由发送
未经身份验证的请求"] --> B["use cache 函数返回
多个类型化数组"] B --> C["Flight 协议将结果序列化为
分块表单数据条目"] C --> D["受攻击者影响的条目与内部
分块共享扁平键空间"] D --> E["反序列化器将条目解析为
内部模型或服务器引用"] E --> F["接受 thenable 混淆或
未经验证的引用 ID"] F --> G["requireModule 解析
引用,执行代码"]

缺失检查位于 D 和 E:修复前,解析前没有机制验证条目种类或服务器引用标识符类型。

攻击者能做什么?

成功利用会以 Next.js 服务器进程身份执行任意代码。该进程通常持有部署密钥、数据库连接和服务凭据,可读取和改写应用能够访问的一切。CVSS v4.0 向量(CVSS:4.0/AV:N/AC:L/AT:P/PR:N/UI:N/VC:H/VI:H/VA:H/SC:H/SI:H/SA:N)将存在漏洞系统和后续系统的机密性、完整性影响均评为高,仅将存在漏洞系统的可用性影响评为高。

就公告说明而言,攻击者需要以下条件:

  • 应用运行 Next.js 16.0.0 至 16.4.0,使用 App Router 且启用 Cache Components。
  • 应用存在返回多个类型化数组的 use cache 函数。
  • 攻击无需身份验证和用户交互,但 CVSS 向量标注存在攻击前提,对应上述依赖功能的触发条件。

Vercel 要求即使没有此类函数也升级,说明不应将这一边界视为可靠防护,因为应用代码会变化,而传输协议是共享基础设施。

为什么修复有效?

补丁提交 a4cea6a 替换所有构建目标中的捆绑 React Server Components 运行时,覆盖服务端与客户端、webpack 与 turbopack、开发与生产。四项更改分别关闭反序列化边界上的一个信任缺口:

-function createModel(response, model) {
-  return model;
+function createModel(response, model, parentObject, key) {
+  return "then" === key && "function" === typeof model ? null : model;
 }

 function loadServerReference(response, metaData, parentObject, key) {
+  if ("then" === key) return null;
+  var id = metaData.id;
+  if ("string" !== typeof id) return null;
   ...

反序列化数据中的 then 函数被丢弃,因此重建对象无法伪装为 Promise。服务器引用必须先携带字符串标识符,才能进行解析或加载。响应对象不再能通过属性遍历到达。条目分组与纠正后的类型化数组序列化,则使分块种类由存储位置决定,而不是由攻击者选择的键决定。

修复完整吗?它在全部十二种捆绑运行时变体中关闭了补丁涉及的每个缺口,覆盖 Next.js 发布的整个相关面。公开材料无法验证原始报告究竟使用了其中一条路径还是组合,Vercel 未公布利用细节。但无论哪种情况,修复都覆盖这一类别,因为进入反序列化器的每条路径现在都会经过新增检查。

如何检查是否已遭入侵?

该公告未发布入侵指标。缺少公开指导时,可检查以下一般信号:

  • Cache Components 路由上意外出现 POST 流量,尤其是表单数据请求体的字段名带序列化前缀而非正常表单字段的请求。
  • 如果缓存处理器记录键,检查其条目中的键或载荷是否畸形,或包含不对应合法缓存写入的分块 ID。
  • flight 反序列化器产生的服务端堆栈跟踪,例如解析服务器引用或初始化模型分块时出现与自身代码不符的错误。
  • 此类错误前后任何代码执行证据,包括新文件、服务器进程出站连接或环境状态变更。

如果发现可疑活动,应将服务器进程视为完全失陷:轮换其可读取的所有密钥,包括部署令牌、数据库凭据和 API 密钥,并从已知可靠状态重建部署。

时间线

  • 2026 年 10 月 14 日:Vercel 发布 GHSA-673q-mjm6-r5xr 和 Next.js 16.4.1,包含 Server Component 传输修复(提交 a4cea6a,编写于 2026 年 10 月 14 日)。
  • 2026 年 10 月 22 日:GitHub Advisory Database 发布并评审该公告。
  • 2026 年 10 月 23 日:本文发布。没有公开概念验证,没有已知在野利用,问题未列入 CISA KEV 目录。

常见问题

有对应 CVE 吗?

截至 2026 年 10 月 23 日,公告 GHSA-673q-mjm6-r5xr 没有 CVE 标识符,在 GitHub Advisory Database 中通过 GHSA ID 跟踪。

必须启用 Cache Components 才受影响吗?

公告描述的漏洞存在于使用 App Router、启用 Cache Components,并有 use cache 函数返回多个类型化数组的应用中。但 Vercel 要求所有用户立即升级,即使没有此类函数;16.4.1 也修复了 Image Optimization RCE,因此实际建议是无论如何都升级。

什么是类型化数组,为什么多个数组很重要?

类型化数组(例如 Uint8Array)是内存块上的定长二进制视图。在 flight 协议中,每个数组都以独立键序列化为独立分块,因此返回多个数组的函数会生成包含多个分块条目的载荷,这正是已发布触发条件描述的形态。

只从缓存函数中移除类型化数组可以吗?

这会从代码中移除已发布的触发条件,但不是修复:Vercel 表示没有临时措施并要求立即升级,且任意代码变更都可能让应用重新满足条件。请升级至 16.4.1。

谁发现并修复了它?

GitHub 用户 evolutionstorm 报告此问题,在 GitHub Advisory Database 条目中被列为发现者。修复由 Vercel 员工在捆绑的 React Server Components 运行时中编写,公告由 Vercel 安全团队发布。

受影响软件有多流行?

next 包在 2026 年 10 月 16-22 日这一周记录了 44,586,009 次 npm 下载,是 JavaScript 生态中部署最广的 Web 框架之一。

使用 Ostorlab 扫描 Next.js 应用,识别各仓库中受影响的 16.x 版本及 use cache 使用情况。

参考资料

  • Vercel 公告 GHSA-673q-mjm6-r5xr:https://github.com/vercel/next.js/security/advisories/GHSA-673q-mjm6-r5xr (2026 年 10 月 23 日核查)
  • React 公告 GHSA-xqc2-xf4c-x3h3,react-server-dom-webpack、react-server-dom-turbopack 和 react-server-dom-parcel 中相同的类型化数组 RCE,已在 19.0.9、19.1.10、19.2.9 和 19.3.1 修复:https://github.com/react/react/security/advisories/GHSA-xqc2-xf4c-x3h3 (2026 年 10 月 26 日核查)
  • GitHub Advisory Database 条目(严重程度、CVSS v4.0 9.5 和 CWE-502 于 2026 年 10 月 24 日确认):https://github.com/advisories/GHSA-673q-mjm6-r5xr
  • 修复提交 a4cea6a,“改进 Server Component 传输协议”:https://github.com/vercel/next.js/commit/a4cea6aec5da89d116b8960e113189cf51745d2f (2026 年 10 月 23 日核查)
  • Next.js 16.4.1 发布说明:https://github.com/vercel/next.js/releases/tag/v16.4.1 (2026 年 10 月 23 日核查)
  • next 的 npm 下载量(2026 年 10 月 16-22 日这一周共 44,586,009 次):https://api.npmjs.org/downloads/point/last-week/next (2026 年 10 月 24 日核查)