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

深度解析

深度解析

GHSA-2464-fhr4-w9xw(CVE-2026-96889):Next.js Image Optimization 中的未授权 RCE

Vercel 将 GHSA-2464-fhr4-w9xw 评为严重,CVSS v4.0 9.5:在基于 glibc 的 Linux 上,如果 Next.js 10.0.0–15.5.27 或 16.0.0–16.4.0 服务器的 Image Optimization API 处理 SVG,未经身份验证的攻击者即可执行代码。漏洞是 sharp 预构建二进制中捆绑的 librsvg 的释放后使用问题(CVE-2026-96889)。Next.js 15.5.28 和 16.4.1 在 Node.js 20.9.0 或更高版本上通过解析到 sharp 0.35.5 修复,它捆绑已修补的 librsvg 2.63.2。

要点速览

Vercel 将 GHSA-2464-fhr4-w9xw 评为严重(CVSS v4.0 9.5):未经身份验证的攻击者可在基于 glibc 的 Linux 上、优化 SVG 的 Next.js 服务器中执行代码。请升级至 Next.js 16.4.1 或 15.5.28。

  • Next.js 内置 Image Optimization API(/_next/image)将攻击者提供的图像字节交给 sharp,其预构建 libvips 二进制内嵌标准 SVG 渲染器 librsvg。根据 RUSTSEC-2026-0305,受影响 librsvg 构建为所有早于修复版本集的版本:主分支 2.63.2 之前,以及稳定系列回移版本 2.62.4、2.61.5、2.60.3 和 2.57.5 之前。这些版本会在 libxml2 仍使用 XML 实体时将其释放,形成释放后使用漏洞,编号 CVE-2026-96889。
  • Next.js 10.0.0 至 15.5.27,以及 16.0.0 至 16.4.0 的每个版本,在基于 glibc 的 Linux 上运行且 SVG 文件能到达优化器时均受影响。Vercel 确认 librsvg 漏洞已有公开概念验证。
  • 截至 2026 年 10 月 23 日,没有已知在野利用,问题未列入 CISA 已知被利用漏洞目录。
  • 升级至 Next.js 16.4.1,或 15.x 分支的 15.5.28。在 Node.js 20.9.0 或更高版本上,全新安装会解析到 sharp 0.35.5(librsvg 2.63.2)。在 15.x 上,升级后运行 npm ls sharp,如果仍为 0.34.x,则安装 sharp@0.35.5。Vercel 公告列出的临时措施是确保 sharp 解析到 0.35.5 或更高版本。

我是否受到影响?

npm 记录 next 在 2026 年 10 月 16-22 日这一周有 44,586,009 次下载。请执行下述两分钟检查。

以下条件全部成立时,您就受到影响:

  • Next.js 运行版本在受影响范围内。
  • 服务器运行基于 glibc 的 Linux,这是 Node 部署的常见情况。
  • sharp 解析到捆绑了未修补 librsvg 的构建版本。下表列出各 sharp 和 librsvg 构建的对应关系。
  • SVG 内容能够到达 Image Optimization API。
分支 受影响版本 修复版本
Next.js 16.x 16.0.0 – 16.4.0 16.4.1
Next.js 10.x – 15.x 10.0.0 – 15.5.27 15.5.28

从 Next.js 15.0.0 起,next 在 optionalDependencies 中列出 sharp,因此默认安装。Next.js 12.3.0、13.5.6 和 14.2.32 未声明 sharp 依赖。在这些分支,优化器只在项目安装 sharp 时加载它,否则回退至 Squoosh。

解析出的 sharp 版本决定服务器内嵌哪一版 librsvg:

sharp 捆绑的 librsvg(sharp-libvips) 状态
0.33.5 2.58.93(通过 @img/sharp-libvips-* 1.0.4) 未修补;不属于 RustSec 矩阵中的任何修复范围
0.34.3 2.60.0(通过 @img/sharp-libvips-* 1.2.0) 未修补;2.60 系列回移修复为 2.60.3
0.34.4 2.61.1(通过 @img/sharp-libvips-* 1.2.3) 未修补;2.61 系列回移修复为 2.61.5
0.34.5 2.61.2(通过 @img/sharp-libvips-* 1.2.4) 未修补;2.61 系列回移修复为 2.61.5
0.35.4 2.62.91(通过 @img/sharp-libvips-* 1.3.3) 未修补;2.62.91 早于 2.63.2 主分支修复和 2.62.4 回移修复
0.35.5 2.63.2(通过 @img/sharp-libvips-* 1.3.4) 包含修复

检查已安装内容:

# Next.js and sharp versions
npm ls next sharp

# Direct read of the installed versions
node -e "console.log('next', require('next/package.json').version)"
node -e "console.log('sharp', require('sharp/package.json').version)"

# Lock file check (lockfileVersion 2 and 3)
grep -n '"node_modules/next"' package-lock.json | head
grep -n '"node_modules/sharp"' package-lock.json | head
# lockfileVersion 1 keys packages by bare name
grep -n '"next": {' package-lock.json | head
grep -n '"sharp": {' package-lock.json | head

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

Sharp 0.35.x 声明 engines.node: >=20.9.0,因此 Node 18 不在支持的运行时范围。该字段不会让 npm 选择较旧的兼容 sharp:除非启用 engine-strict,npm 仅将它视为建议,并警告运行时不兼容。

  • Next.js 15.0.0 的 ^0.33.5 依赖范围允许 sharp 0.33.5,它捆绑 librsvg 2.58.93。
  • Next.js 15.5.28 的 ^0.34.3 || ^0.35.5 范围同时允许未修补的 0.34.x 和已修补的 0.35.5;现有锁文件可能保留 0.34.x。

sharp/librsvg 表中的 0.33.x 和 0.34.x 构建均不含已修补的 librsvg。

如何修复?

升级 Next.js。在 Node.js 20.9.0 或更高版本上,全新依赖解析会拉取 sharp 0.35.5(librsvg 2.63.2)。注意两个例外:

  • 在 15.x 分支,范围仍接受 ^0.34.3,因此现有锁文件可能保留未修补的 0.34.x。升级后运行 npm ls sharp,如果仍为 0.34.x,显式安装 sharp@0.35.5。
  • 使用 15.x 分支的 Node 18 主机必须先迁移至 Node.js 20.9.0 或更高版本,修复才能生效。
# Next.js 16 line
npm install next@16.4.1
# or: pnpm add next@16.4.1   |   yarn add next@16.4.1

# Next.js 15 line
npm install next@15.5.28

如果暂时不能升级 Next.js,单独强制升级 sharp。公告列出的临时措施是确保 Next.js 使用的 sharp 为 0.35.5 或更高版本。这需要 Node.js 20.9.0 或更高版本,因为只有 sharp 0.35.x 分支捆绑了修补后的 librsvg。

npm install sharp@0.35.5

只有当 Next.js 自身的 sharp 范围接受 0.35.5 时,该安装才会改变它加载的版本。Next.js 15.5.27 声明 ^0.34.3 || ^0.35.4,可以接受。Next.js 15.0.0 声明 ^0.33.5,不能接受,因此其嵌套的 0.33.5 仍会保留。这种情况下,在 package.json 强制指定解析版本并重新安装:

{
  "overrides": { "sharp": "0.35.5" }
}

pnpm 使用 pnpm.overrides,Yarn 使用 resolutions。

临时措施的局限是仅替换捆绑 librsvg,不改变优化器处理请求的方式。

  • 16.4.1 修复要求 sharp ^0.35.5,它提供已修补的 librsvg 2.63.2。
  • 15.5.28 修复在 ^0.34.3 || ^0.35.5 范围中保留了 ^0.34.3 下限。该下限不包含修复:0.34.x 构建捆绑 librsvg 2.60.0 至 2.61.2,均低于对应 2.60.3 和 2.61.5 回移版本。
  • 在 Node 18 上,15.x 升级并不完整。迁移至 Node.js 20.9.0 或更高版本,以在支持的运行时上运行 sharp 0.35.5,再验证解析出的 sharp 版本。

根本原因是什么?

释放后使用是指代码释放内存后仍继续使用其指针。librsvg 是通过 libxml2 解析 XML 来渲染 SVG 的 Rust 库;在其中,带有重复实体声明的嵌套 XInclude 会释放外层解析仍持有的 xmlEntity 结构。XInclude 是让一个 XML 文档引入另一个文档节点的机制。Red Hat 的 CVE-2026-96889 记录描述了这一过程。

RUSTSEC-2026-0305 将失效过程描述为四步:

  1. 展开内部实体时,libxml2 递归解析一个 XInclude 文档,该文档重新声明同名实体。
  2. 两次解析共享 librsvg 的 XmlState 实体映射,添加重复项会替换原始条目。
  3. 丢弃被替换的 xmlEntity 时调用 xmlFreeNode(),释放其内存。
  4. 外层 xmlCtxtParseEntity() 继续访问这个已释放的 144 字节结构。

一句话概括:实体映射替换条目时没有检查 libxml2 是否仍持有其指针,因此跨 XInclude 边界重新声明实体名的文档,会将解析器内部指针变成悬空指针。

这就是缺失的生命周期检查,也是上游修复消除的问题。Librsvg 提交 8a1b0cd319e9af2d1e9cf878081dd77f227a0504 停止释放 libxml2 仍在使用的 xmlEntity 指针。修复最先在 librsvg 2.63.2 发布,并回移至 2.62.4、2.61.5、2.60.3 和 2.57.5,于 2026 年 9 月 23 日公开。

Next.js 通过图像优化进入这段代码。/_next/image 端点接受 url 参数,检查它是否符合配置的允许列表(旧分支为 images.domains,新分支为 images.localPatterns 和 images.remotePatterns),获取字节,再传给通过 libvips 加载图像的 sharp。Next.js 16.4.0 优化器在 packages/next/src/server/image-optimizer/transform.ts 中显式启用 libvips 的 SVG 加载器:

// packages/next/src/server/image-optimizer/transform.ts (v16.4.0)
export function getSharp(concurrency, operationCache) {
  ...
  _sharp.block({ operation: ['VipsForeignLoad'] })
  _sharp.unblock({
    operation: [
      'VipsForeignLoadHeif',   // avif
      'VipsForeignLoadJpeg',
      'VipsForeignLoadNsgif',
      'VipsForeignLoadPng',
      'VipsForeignLoadSvg',    // librsvg parses SVG bytes here
      ...
    ],
  })

当 libvips 将输入识别为 SVG 时,VipsForeignLoadSvg 将文档交给 librsvg,实体映射漏洞便可从请求字节触发。15.5.x 优化器中也有同样的 VipsForeignLoadSvg 解锁。在更早的受影响版本中,连接方式不同:例如 Next.js 14.2.x 将无法通过魔数字节识别的任何缓冲区直接交给 sharp 检测格式,代码位于 packages/next/src/server/image-optimizer.ts(v14.2.32):

// Fallback to sharp if available
if (sharp) {
  const meta = await sharp(buffer)
    .metadata()
    .catch((_) => null)
  switch (meta?.format) {
    ...
    case 'svg':
      return SVG

注意该版本的顺序:sharp(buffer).metadata() 在优化器的 dangerouslyAllowSVG 检查前解析文件,因此在这条代码路径中,SVG 开关只限制是否返回图像,不能作为阻止解析的边界。

如何利用?

没有针对 Next.js 的公开端到端利用。librsvg 漏洞本身已有公开复现程序:GNOME GitLab 跟踪条目标记为包含利用材料,CISA 针对 CVE-2026-96889 的 vulnrichment 记录将利用标为“poc”,技术影响标为“total”。此处不重现代码,下面仅描述公开路径。

  1. 攻击者构造包含第二个文档 XInclude 的 SVG,第二个文档声明一个与外层文档中已有实体同名的 XML 实体。
  2. 攻击者将 SVG 放在目标优化器可获取的位置:能通过应用 images 允许列表的本地路径或远程主机。
  3. 攻击者通过图像优化端点请求该文件,使用应用配置的 deviceSizes 或 imageSizes 中的宽度,以及允许范围内的质量,例如 GET /_next/image?url=https%3A%2F%2Fcdn.attacker.example%2Favatar.svg&w=640&q=75。
  4. 优化器获取字节并传给 sharp。Libvips 将文档识别为 SVG,librsvg 随后解析。
  5. 实体展开期间,嵌套 XInclude 重新声明实体。映射替换并释放旧条目,而外层解析仍保留指针。
  6. 外层解析器读取已释放的 144 字节 xmlEntity,形成释放后使用。在 glibc 堆上,能够控制释放内容及分配序列的攻击者可将其转为 Node.js 服务器进程中的任意代码执行。

公告将 RCE 范围限定于基于 glibc 的 Linux,因为 Next.js 安装的预构建 sharp 二进制为 glibc 构建;musl 构建属于独立软件包。

利用如何穿过优化器?

flowchart LR A["攻击者托管带嵌套 XInclude
和重复实体的 SVG"] --> B["GET /_next/image?url=...&w=...&q=..."] B --> C["URL 允许列表检查
images 配置"] C --> D["优化器将字节传给 sharp,
libvips 选择 VipsForeignLoadSvg"] D --> E["librsvg 实体映射
替换并释放仍在使用的条目"] E --> F["外层 xmlCtxtParseEntity 读取
已释放的 144 字节 xmlEntity"] F --> G["释放后使用导致
服务器进程内代码执行"]

缺失检查位于图中的 E 节点:释放实体前没有验证它是否已不再被使用。

攻击者能做什么?

成功利用以 Next.js 服务器进程权限运行任意代码,通常就是提供应用服务的 Node.js 进程。这意味着访问该进程能触及的一切:环境变量和部署凭据、内部服务、数据库,还能修改提供给用户的响应。失败或部分利用也会使进程崩溃,因为无论攻击者是否赢得分配器竞态,悬空指针都会被解引用。

攻击需要的条件:

  • 无需身份验证或用户交互,依据 CVSS v4.0 向量 AV:N/AC:L/AT:P/PR:N/UI:N(网络、低复杂度、无需权限、无需用户交互;存在攻击前提)。
  • 服务器运行基于 glibc 的 Linux。
  • sharp 解析到捆绑未修补 librsvg 的构建(0.35.4 捆绑 librsvg 2.62.91;0.34.x 捆绑 2.60.0、2.61.1 或 2.61.2;0.33.5 捆绑 2.58.93)。
  • SVG 字节能到达优化器:攻击者需要可通过应用 images 模式允许列表的源 URL。在 Next.js 14.2.x 中,SVG 解析发生在 dangerouslyAllowSVG 检查前,因此该标志仅限制响应,不限制存在漏洞的解析。
  • 应用接受的宽度和质量组合。

为什么修复有效?

Vercel 通过升级 sharp 依赖带来的捆绑 librsvg 修复问题,而非改变请求处理。16.x 修复提交(9571ec8)提高了 packages/next/package.json 中的 sharp 要求:

   "optionalDependencies": {
-    "sharp": "^0.35.4"
+    "sharp": "^0.35.5"
   }

15.x 修复提交(5e3b687)同样调整范围:"sharp": "^0.34.3 || ^0.35.4" 变为 "^0.34.3 || ^0.35.5"。Sharp 0.35.5 将预构建 libvips 包从 @img/sharp-libvips-* 1.3.3 换为 1.3.4。根据发布说明,1.3.4 捆绑 rsvg 2.63.2;RustSec 将其列为最早的主分支修复版本,包含上游提交 8a1b0cd3。该提交停止释放 libxml2 仍在使用的 xmlEntity 指针。漏洞消除后,嵌套 XInclude 文档不再产生悬空引用,因此崩溃和代码执行路径都不复存在。

修复完整吗?对于捆绑二进制路径,是的:已修补 librsvg 消除根本原因,公告版本范围也对应依赖变更。仍有两个注意点:

  • 固定的 sharp 版本。将 sharp 固定在 0.35.5 以下,包括任何 0.34.x 版本,即使 Next.js 已修补,也会保留存在漏洞的 librsvg。因此公告以 sharp 版本定义临时措施。
  • “可能”RCE 仍意味着暴露。公告将影响称为“可能”的 RCE,因为释放后使用利用依赖分配器行为。应将所有受影响部署视为暴露,而非按可能性分级处理。

如何检查是否已遭入侵?

该问题未发布入侵指标。缺少公开指导时,可围绕图像端点查找以下一般信号:

  • 对 /_next/image 的请求中,url 参数指向意外主机或路径,尤其是最终提供 SVG 内容的目标。
  • 优化器集中返回 HTTP 400;当 dangerouslyAllowSVG 禁用时,它会拒绝 SVG 内容,探测流量可能留下这种痕迹。
  • 与图像优化相关联的 Node.js 进程崩溃或重启,因为同一缺陷可能使解析器崩溃,而非将控制权交给攻击者。
  • 日志中的 sharp 错误,例如“Input buffer contains unsupported image format”,优化器在加载中途失败时会记录该消息。

如果发现可疑活动,轮换服务器进程能访问的所有凭据,因为在该进程中执行代码就能读取它们。

时间线

  • 2026 年 9 月 23 日:Rafael B. Dias 向 Red Hat 报告 librsvg 释放后使用问题。当日与 RUSTSEC-2026-0305 和 CVE-2026-96889 一同披露。
  • 2026 年 9 月 25 日:CISA 针对 CVE-2026-96889 的 ADP vulnrichment 记录公开概念验证(“Exploitation: poc”,技术影响“total”)。
  • 2026 年 9 月 27 日:sharp-libvips 1.3.4 携带 librsvg 2.63.2 发布,sharp 0.35.5 随之发布。
  • 2026 年 10 月 14 日:Vercel 发布 GHSA-2464-fhr4-w9xw,以及升级 sharp 的 Next.js 15.5.28 和 16.4.1。
  • 2026 年 10 月 22 日:GitHub Advisory Database 发布并评审该公告。
  • 2026 年 10 月 23 日:本文发布。没有已知在野利用;问题未列入 CISA KEV 目录。

常见问题

默认 Next.js 配置下,我的应用会暴露吗? 对于使用默认加载器和 next/image 的应用,Image Optimization API 默认启用。SVG 内容能否到达 sharp,取决于对应版本的检测路径和 images 配置。无论配置如何都应升级。

我究竟安装了 sharp 吗? 从 15.0.0 起,Next.js 在可选依赖中列出 sharp,因此受支持平台上的普通 npm install 会包含它。我们检查的 15.0.0 之前版本(12.3.0、13.5.6、14.2.32)未列出它,所以只有项目自行安装才会存在。运行 npm ls sharp。如果为 0.35.5 或更高版本,则包含已修补的 librsvg 2.63.2;0.34.x 则没有,这些版本捆绑 2.60.0、2.61.1 或 2.61.2,均早于对应的 2.60.3 和 2.61.5 回移版本。

Next.js 公告本身有 CVE 吗? 截至 2026 年 10 月 23 日,GitHub 公告 GHSA-2464-fhr4-w9xw 没有自己的 CVE。底层 librsvg 漏洞是 CVE-2026-96889,NVD 和 Linux 发行版使用该编号跟踪。

应用只提供 PNG 和 JPEG,需要担心吗? 公告将漏洞范围限定于图像优化使用的 SVG 文件。如果应用允许列表无法被用来向优化器提供 SVG,就不在所描述路径中。但安全做法仍然是执行一行升级命令。

Alpine Linux(musl)能保护我吗? 公告将 RCE 限定于基于 glibc 的 Linux。musl 预构建属于独立软件包,公告未对它们作出结论。不要将平台差异视为修复,仍应升级 sharp 和 Next.js。

它正在被利用吗? 截至 2026 年 10 月 23 日,没有已知在野利用,问题未列入 CISA KEV 目录。librsvg 漏洞已有公开概念验证,因此应假定机会型攻击者会关注,并据此修补。

使用 Ostorlab 源代码扫描检查 Next.js 仓库,再通过上述版本检查验证每个部署实际安装的 Next.js 和 sharp 构建。

参考资料

  • Vercel 公告 GHSA-2464-fhr4-w9xw:https://github.com/vercel/next.js/security/advisories/GHSA-2464-fhr4-w9xw (2026 年 10 月 23 日核查;向发现者 randomguy6407 和 rafabd1 致谢,2026 年 10 月 27 日核查)
  • GitHub Advisory Database 条目:https://github.com/advisories/GHSA-2464-fhr4-w9xw (2026 年 10 月 23 日核查)
  • CVE-2026-96889 记录(Red Hat CNA):https://cveawg.mitre.org/api/cve/CVE-2026-96889 (2026 年 10 月 23 日核查)
  • RustSec 公告 RUSTSEC-2026-0305(2026 年 10 月 24 日复查修补版本矩阵):https://rustsec.org/advisories/RUSTSEC-2026-0305.html
  • Librsvg 问题跟踪条目(工作项 #1241),引用修复提交 8a1b0cd319e9af2d1e9cf878081dd77f227a0504:https://gitlab.gnome.org/GNOME/librsvg/-/work_items/1241 (2026 年 10 月 23 日核查)
  • Next.js 16.x 修复提交(升级 sharp):https://github.com/vercel/next.js/commit/9571ec899f063df6533351bec390ccb2cc0af6a3 (2026 年 10 月 23 日核查)
  • Next.js 15.x 修复提交(升级 sharp):https://github.com/vercel/next.js/commit/5e3b687b5edb868b064bdc058d768a7021e7f6ad (2026 年 10 月 23 日核查)
  • Next.js 16.4.1 发布说明:https://github.com/vercel/next.js/releases/tag/v16.4.1 (2026 年 10 月 23 日核查)
  • sharp 0.35.5 发布说明:https://github.com/lovell/sharp/releases/tag/v0.35.5 (2026 年 10 月 23 日核查)
  • sharp 0.35.5 包元数据(固定 @img/sharp-libvips-* 1.3.4,Node 引擎 >=20.9.0):https://raw.githubusercontent.com/lovell/sharp/v0.35.5/package.json (2026 年 10 月 27 日核查)
  • sharp 0.33.5 包元数据(固定 @img/sharp-libvips-* 1.0.4):https://raw.githubusercontent.com/lovell/sharp/v0.33.5/package.json (2026 年 10 月 27 日核查)
  • @img/sharp-libvips-linux-x64 1.0.4 发布包,versions.json(rsvg 2.58.93):https://registry.npmjs.org/@img/sharp-libvips-linux-x64/-/sharp-libvips-linux-x64-1.0.4.tgz (2026 年 10 月 27 日核查)
  • Next.js 包元数据,标签 v14.2.32(无 sharp 依赖)和 v15.0.0("sharp": "^0.33.5"):https://github.com/vercel/next.js/blob/v14.2.32/packages/next/package.json 和 https://github.com/vercel/next.js/blob/v15.0.0/packages/next/package.json (2026 年 10 月 27 日核查)
  • sharp 0.34.3 包元数据(固定 @img/sharp-libvips-* 1.2.0,Node 引擎范围):https://raw.githubusercontent.com/lovell/sharp/v0.34.3/package.json (2026 年 10 月 24 日核查)
  • sharp-libvips 1.2.0 构建版本(rsvg 2.60.0):https://raw.githubusercontent.com/lovell/sharp-libvips/v1.2.0/versions.properties (2026 年 10 月 24 日核查)
  • sharp-libvips 1.2.3 构建版本(rsvg 2.61.1):https://raw.githubusercontent.com/lovell/sharp-libvips/v1.2.3/versions.properties (2026 年 10 月 24 日核查)
  • sharp-libvips 1.2.4 构建版本(rsvg 2.61.2):https://raw.githubusercontent.com/lovell/sharp-libvips/v1.2.4/versions.properties (2026 年 10 月 24 日核查)
  • sharp-libvips 1.3.4 发布说明(rsvg 2.63.2):https://github.com/lovell/sharp-libvips/releases/tag/v1.3.4 (2026 年 10 月 23 日核查)
  • sharp-libvips 1.3.3 发布说明(rsvg 2.62.91):https://github.com/lovell/sharp-libvips/releases/tag/v1.3.3 (2026 年 10 月 23 日核查)
  • Next.js 优化器源码,标签 v16.4.0:https://github.com/vercel/next.js/blob/v16.4.0/packages/next/src/server/image-optimizer/transform.ts (2026 年 10 月 23 日核查)
  • Next.js 优化器源码,标签 v14.2.32:https://github.com/vercel/next.js/blob/v14.2.32/packages/next/src/server/image-optimizer.ts (2026 年 10 月 23 日核查)
  • next 的 npm 下载量(2026 年 10 月 16-22 日这一周共 44,586,009 次):https://api.npmjs.org/downloads/point/last-week/next (2026 年 10 月 24 日核查)
  • npm 包元数据文档(除非设置 engine-strict,否则 engines 仅为建议):https://docs.npmjs.com/cli/v11/configuring-npm/package-json/#engines (2026 年 10 月 28 日核查)