10 月 21 日,Node.js 官方向三个仍在维护的版本分支发布了安全更新,共修复 10 个漏洞,其中 4 个高危、3 个中危、3 个低危。
这次漏洞涉及 Brotli 解压、HTTPS 证书验证、DNS 域名解析、随机数生成等功能。最严重的一个可能导致远程代码执行。
另外,Node.js 还首次引入了内置证书公钥黑名单,将近期发生私钥泄露事件的 8 枚 eMudhra 中间 CA 证书列入封锁名单。
如果你的项目使用 Node.js,建议检查一下开发环境和线上服务的运行时版本。
一、Node.js 这次更新了三个版本
10 月 21 日发布的安全版本分别是:
| 版本分支 | 安全更新版本 |
|---|---|
| Node.js 22.x | v22.23.4 |
| Node.js 24.x | v24.22.1 |
| Node.js 26.x | v26.12.1 |
Node.js 20.x 已于 2026 年 4 月 30 日停止维护,25.x 则在 6 月 1 日停止维护。这两条版本线没有收到此次安全补丁。
目前使用 22.x 或 24.x 的项目,可以优先升级到对应分支的安全版本。仍在使用 20.x、25.x 等停止维护版本的项目,需要迁移到受支持的版本。
生产环境建议优先选择 LTS 版本,降低跨版本升级带来的兼容性风险。
二、10 个安全漏洞,具体影响什么?
这次漏洞主要集中在 Node.js 的底层组件和内置 API,其中有几个与日常开发关系比较密切。
1. Brotli 解压漏洞:可能导致远程代码执行
CVE-2026-111497|高危
Brotli 是一种常见的压缩算法,网页传输中经常使用。比如我们在 HTTP 响应头里看到的 Content-Encoding: br,就是采用了 Brotli 压缩。
Node.js 内置了 Brotli 解压功能,开发者可以通过 node:zlib 模块使用。
这次发现,Brotli 解码器存在越界写入漏洞。
程序在解压数据时,可能将内容写入原本不应该访问的内存区域。越界写入可能导致程序崩溃,严重时还可能被攻击者利用来执行恶意代码。
Node.js 官方将这个漏洞评为高危,并明确提到了远程代码执行的风险。
不过,官方目前没有披露具体的触发条件,也没有公布完整的攻击利用方式。
修复方案是同步 Google Brotli 项目的相关改动,让解码器能够更早识别和拒绝异常数据。
如果你的服务需要接收并解压外部数据,这个漏洞应优先处理。
2. HTTPS 证书验证漏洞:可能认错服务器
CVE-2026-105483、CVE-2026-106069|高危
Node.js 建立 HTTPS 连接时,会检查服务器提供的数字证书。
其中有一项工作,就是确认你访问的地址和证书上登记的地址是否一致。
比如你访问 192.168.1.10,对方提供的证书却属于另一个 IP,正常情况下应该拒绝连接。
这次发现的两个高危漏洞,都与 IP 地址的特殊写法有关。
一种情况是使用全角数字。例如,把 127 写成 127。
另一种情况是使用了不规范、但在某些解析环节中仍能被识别为 IP 地址的格式。
由于不同环节对这些地址的处理方式不一致,可能造成证书主机名验证绕过。
两个漏洞的影响范围略有不同:
- CVE-2026-105483:影响 Node.js 24.x 和 26.x。
- CVE-2026-106069:影响 Node.js 22.x、24.x 和 26.x。
此外,还有一个中危漏洞 CVE-2026-106072,同样涉及非标准 IPv4 地址的证书验证问题。
这次修复加强了 IP 地址的规范性检查,避免通过特殊地址格式绕过验证。
3. DNS 域名解析漏洞:查询的域名可能被截断
CVE-2026-105482|高危
Node.js 提供了 dns.resolve() 等 API,用于查询域名对应的 IP 地址。
这次发现,当传入的域名中包含 NUL 空字符时,程序可能将域名截断。
例如,程序原本接收到的域名是:
example.com\0.attacker.com
如果底层把 NUL 当作字符串结束标记,最终处理的可能只有 example.com。
如果业务代码允许用户输入域名,又使用这些域名执行 DNS 查询,就需要检查输入校验逻辑。
因为程序检查的域名和实际查询的域名可能出现差异。
新版本已经修复了这个问题。
4. 随机数漏洞:每次启动生成相同的随机值
CVE-2026-106074|中危
Node.js 提供了 crypto.randomUUID() 和 crypto.randomInt() 等 API,用于生成随机标识和随机整数。
正常情况下,不同进程生成的随机结果应该相互独立。
但如果开发者使用启动快照(Startup Snapshot),或者将程序打包成单个可执行文件(SEA),旧版本可能会把随机数缓存一同保存进去。
这样一来,使用相同快照启动的进程,就可能重复生成相同的随机值。
如果这些随机值被用于安全令牌、身份验证或者其他依赖随机性的业务,就可能引发安全问题。
使用普通 Node.js 启动方式的项目,与使用 Startup Snapshot、SEA 的项目,受这个漏洞影响的条件并不相同。
5. 其余四个漏洞
另外四个漏洞分别涉及:
| CVE 编号 | 等级 | 问题 |
|---|---|---|
| CVE-2026-105481 | 中危 | HTTP Keep-Alive 连接可能处理请求发送前已经写入的响应 |
| CVE-2026-106070 | 低危 | ZIP 文件头校验失败后可能返回攻击者可控的数据 |
| CVE-2026-106071 | 低危 | 权限模型中的通配符路径匹配可能授予过多权限 |
| CVE-2026-106073 | 低危 | fs.realpathSync() 可能绕过权限模型的检查 |
ZIP 文件处理漏洞和其中一个权限模型漏洞只影响 Node.js 26.x。
除了这 10 个漏洞,Node.js 还更新了 c-ares、OpenSSL、SQLite、undici 等内置依赖,用来修复这些组件已经公开的安全问题。
三、eMudhra 的 8 枚证书出了什么问题?
这次 Node.js 更新还有一项内容,与几天前发生的 eMudhra 证书安全事件有关。
10 月 17 日,安全研究人员发现,印度证书颁发机构 eMudhra 的 8 枚中间 CA 证书,其私钥生成过程使用了随机性不足的数据。
正常情况下,数字证书所使用的私钥应该很难被猜测或推算。
但这批证书的私钥存在严重的生成缺陷,攻击者可以从公开信息中推算出私钥,从而获得伪造证书的能力。
为什么私钥泄露会影响 HTTPS?
平时访问 HTTPS 网站,浏览器会检查网站提供的数字证书,以确认当前连接的服务器身份。
网站的数字证书通常由受到信任的 CA 机构签发。
CA 可以理解为数字证书的签发机构,而中间 CA 则获得了上级 CA 的授权,可以继续签发证书。
这次 eMudhra 出问题的,就是 8 枚中间 CA 证书对应的私钥。
一旦攻击者掌握这些私钥,就可能为其他网站签发看起来合法的假证书。
比如,攻击者可以伪造某个网站的证书。如果用户的设备仍然信任这枚中间 CA,而攻击者又具备拦截网络流量的能力,就可能冒充目标网站。
HTTPS 连接表面上仍然使用了加密,但用户连接的服务器可能已经被替换。
根据 Google 10 月 20 日发布的报告,Chrome 在收到研究人员报告后不到两小时,就完成了验证并下发了证书封锁更新。
随后,Firefox、Apple、Microsoft 等平台也采取了相应措施。
浏览器已经拉黑,为什么 Node.js 还要更新?
因为浏览器和 Node.js 对证书的信任管理方式不同。
Chrome 有 CRLSet,Firefox 有 OneCRL。这些机制可以帮助浏览器快速封锁存在安全问题的证书。
Node.js 虽然内置了 Mozilla 根证书列表,但此前没有与浏览器相同的证书封锁名单实时分发机制,默认也不会在线检查每一枚证书的撤销状态。
如果一枚中间 CA 证书的私钥已经泄露,但 Node.js 仍然能够通过它构建出一条通向可信根 CA 的证书链,旧版本就可能继续接受它。
因此,Chrome 已经不信任的证书,旧版 Node.js 不一定会同步拒绝。
此次 Node.js 引入了内置的证书公钥黑名单,首批封锁的就是这 8 枚 eMudhra 中间 CA 的公钥。
Node.js 会根据公钥信息的 SHA-256 哈希值进行匹配。当证书链中出现被封锁的公钥时,正常启用证书校验的 TLS 连接会被拒绝。
这项机制覆盖 Node.js 创建的相关 TLS 安全上下文,包括 SecureContext、QUIC 和 DTLS。
不过,如果开发者主动关闭了证书校验,例如使用 rejectUnauthorized: false,仍然会破坏正常的证书验证机制。
Mozilla 工程师 Dennis Jackson 还提供了一个测试页面,可以帮助开发者检查客户端是否仍然信任受影响的证书:
https://emudhra.we-have-a-problem.com/
如果你的 Node.js 服务需要连接外部 HTTPS API,可以使用实际运行服务的环境进行检测。
四、怎么检查自己的 Node.js 项目?
首先打开终端,执行:
bash
node -v
查看当前 Node.js 版本。
如果低于 10 月 21 日对应分支的安全版本,就需要升级。
但对于已经上线的服务,只检查本地电脑还不够。
比如,你已经把 Mac 上的 Node.js 升级到了 v24.22.1,线上 Docker 镜像却仍然使用旧版本,那么生产环境的漏洞并没有修复。
可以按照下面的顺序处理:
第一步:检查运行环境
检查本地开发环境、Docker 镜像、云服务器和 CI/CD 构建环境使用的 Node.js 版本。
第二步:升级 Node.js
根据当前项目所使用的版本分支,升级到对应的安全版本。
如果项目使用的是 20.x、25.x 等停止维护版本,需要安排跨版本迁移,并检查相关依赖的兼容性。
第三步:重新构建和测试
对于 Docker 部署的项目,更新基础镜像后重新构建。
如果项目使用了 SEA 或启动快照,也需要重新生成相关产物。
完成后运行项目现有的单元测试、集成测试和构建测试,检查业务是否受到影响。
第四步:检查 HTTPS 配置
重点搜索以下配置:
bash
NODE_TLS_REJECT_UNAUTHORIZED=0
javascript
rejectUnauthorized: false
如果代码中存在这些设置,需要确认原因,并尽可能恢复正常的证书验证机制。
还有一点,npm audit 只能帮助检查 npm 项目依赖中的已知漏洞,不能代替 Node.js 运行时的安全升级。
本次修复涉及 Node.js 自身,单纯执行 npm update 并不能解决这些问题。
五、用 AI Agent 自动完成 Node.js 安全排查和升级
现在使用 Codex、OpenCode、Claude Code 等 AI 编程工具,已经可以让 Agent 自动检查项目配置、修改代码、运行测试。
这次 Node.js 安全更新也可以交给 AI Agent 来处理。
不过,漏洞主要存在于 Node.js 运行时本身,Agent 无法仅靠修改业务代码完成修复。
它需要检查项目的运行环境、升级 Node.js、重新构建应用,再运行测试确认结果。
下面这段提示词可以直接复制到支持终端操作的 AI 编程工具中。
AI Agent 自动修复提示词
**任务:检查并修复当前项目中与 Node.js 2026 年 10 月 21 日安全更新有关的漏洞。**
请先阅读 Node.js 官方安全公告:
https://nodejs.org/en/blog/vulnerability/october-2026-security-releases
本次安全更新的最低修复版本:
- Node.js 22.x:v22.23.4
- Node.js 24.x:v24.22.1
- Node.js 26.x:v26.12.1
**一、检查当前项目**
1. 读取项目结构及相关配置文件,确认项目使用的 Node.js 版本。
2. 检查 `package.json`、`.nvmrc`、`.node-version`、`Dockerfile`、`docker-compose.yml`、CI/CD 配置和部署脚本。
3. 检查 npm、pnpm、yarn 等包管理器及锁文件。
4. 区分本地开发、构建、测试、Docker 容器及生产环境的 Node.js 版本。
5. 搜索项目是否使用以下功能:
- Brotli 压缩和解压
- `dns.resolve()` 等 DNS 查询 API
- HTTPS/TLS 证书验证
- `crypto.randomUUID()`、`crypto.randomInt()`
- Startup Snapshot、SEA
- Node.js 实验性权限模型
6. 检查是否存在跳过 HTTPS 证书验证的配置。
7. 输出检查结果,并列出受影响的文件、配置及潜在风险。
**二、执行升级和修复**
1. 检查 Git 工作区,保留当前所有未提交的修改,并创建独立的修复分支。
2. 优先在原有受支持的 Node.js 主版本分支内升级。
3. 如果当前版本已停止维护,选择合适的 LTS 版本并检查兼容性。
4. 更新项目中声明的 Node.js 版本,包括版本管理文件、Docker 基础镜像及 CI/CD 配置。
5. 保留现有包管理器和锁文件,不要顺带升级无关依赖。
6. 检查 TLS 证书验证配置,修复不安全设置。
7. 如果项目使用了 Brotli、DNS 或其他受影响功能,检查相关输入校验代码,必要时补充安全验证。
8. 如果使用 Startup Snapshot 或 SEA,检查随机数生成逻辑,并重新构建相关产物。
9. 不要通过关闭 TLS 证书校验来绕过升级后的兼容性问题。
10. 不要使用自行维护的不完整证书黑名单替代 Node.js 官方修复。
**三、运行测试**
完成修改后,执行项目现有的测试和构建命令,包括:
- 单元测试
- 集成测试
- TypeScript 类型检查(如果项目使用)
- 代码静态检查
- 应用构建测试
- 已有接口和业务功能测试
如果项目存在相应功能,请补充 Brotli 异常数据处理、DNS 输入校验、HTTPS 证书验证及随机数生成相关测试。
如果项目使用 Docker,需要检查最终运行镜像中的 Node.js 版本,而不只是 Dockerfile 中填写的版本。
检查是否仍然信任受影响的 eMudhra 中间 CA 证书。无法完成验证时,应明确标注为未验证,不能将普通网络连接失败当作安全测试通过。
**四、提交结果报告**
完成后输出 Markdown 格式的修复报告,包括:
1. 升级前后的 Node.js 版本。
2. 涉及的 CVE 编号及影响范围。
3. 实际修改的文件列表。
4. 已完成的安全修复。
5. 构建和测试结果。
6. 尚未修复或无法验证的问题。
7. Git 变更摘要。
8. 生产环境部署、验证及回滚建议。
**执行限制:**
- 不要直接修改生产环境。
- 不要擅自部署线上服务。
- 不要删除现有业务功能或测试代码。
- 不要为了通过测试而关闭安全检查。
- 不要覆盖用户尚未提交的 Git 修改。
- 如果发现升级涉及重大兼容性变化,先说明具体影响,再决定处理方式。
- 所有修复结果都必须有对应的检查记录或测试依据。
先完成环境审计,再实施修改与测试。最后给出完整报告。
写在最后
这次 Node.js 修复的漏洞,很多都来自开发者日常使用的底层功能。
像 Brotli 解压、DNS 查询、HTTPS 证书验证,平时基本不需要开发者自己实现,直接调用 Node.js 提供的 API 就可以。
但这些底层组件出现漏洞时,使用它们的应用也可能受到影响。
我自己平时也会使用 Node.js 开发一些网站和自动化工具,项目多了之后,确实容易忽略运行环境的版本管理。特别是 Docker 部署的项目,本地 Node.js 已经更新,容器却可能一直使用旧镜像。
如果你的项目还在使用 Node.js 20.x,或者生产环境长期没有更新过,可以借这次安全公告做一次检查。
你平时会定期升级 Node.js 的运行时版本吗,还是一般等到项目出了兼容性问题才升级?
欢迎在评论区交流。