2026 年 10 月 21 日,Node.js 发布三个受支持分支的安全更新,修复 10 个漏洞,其中 4 个为高危。最严重的是 CVE-2026-111497:内置 Brotli 解码器存在越界写,官方描述为「可导致远程代码执行」。修复版本为 22.23.4、24.22.1、26.12.1,已停止维护的 20.x 及更早分支不再提供补丁。
事件概述
Brotli 是 Google 推出的 HTTP 压缩格式,在同等压缩率下比 gzip 更省带宽,主流浏览器普遍在 Accept-Encoding: br 中声明支持。Node.js 通过 node:zlib 内置了 Brotli 解码能力,只要进程解压了攻击者可控的 Brotli 数据,就落在影响面内。
技术细节
官方未给出触发条件与利用细节。第三方分析指出,修复方式是从上游 Brotli 挑拣提交 0ed4268a,让解码器在遇到「流中声明只有一种块类型、却出现块切换」的畸形数据时立即失败。缺陷由 Node.js TSC 主席 Matteo Collina 报告,Antoine du Hamel 修复。
暴露路径三条:
- 直接调用
node:zlib的 Brotli 解压接口处理不可信数据; - 使用
fetch()请求返回 Brotli 压缩响应的外部地址; - body-parser 一类自动解压请求体的中间件。
同批另外三个高危都在证书与域名校验上:CVE-2026-105483 在用全角数字书写 IP 地址时绕过 TLS 主机名校验(仅 24.x、26.x);CVE-2026-106069 在主机名松散解析为 IP 时校验失效;CVE-2026-105482 使 dns.resolve 遇空字节截断域名,导致查询名与实际解析名不一致。三者都能让客户端接受非目标站点的证书,中间人风险上升。
中危项有一条值得记住:CVE-2026-106074,crypto.randomUUID() 与 randomInt() 的熵缓存在启动快照与单可执行文件(SEA)打包时被写进镜像,每个进程会重复生成同一批随机值。低危项则是 ZIP 头校验失败后返回攻击者字节(CVE-2026-106070,仅 26.x)与 Permission Model 绕过。
影响评估
Node.js 未给这 10 个漏洞发布 CVSS 分数,仅标 High。Vercel 公告更进一步,称研究者在其未修补版本上「演示了进程内存泄露与命令执行」,但这属 Vercel 表述,不是 Node.js 官方结论。截至 10 月 22 日无在野利用报告;同日公开的 PoC 仅在刻意弱化的测试构建上取得代码执行,标准构建上作者只看到崩溃与有限的进程内存读取。
修复建议
node --version # 应为 v22.23.4 / v24.22.1 / v26.12.1
# Dockerfile
FROM node:22.23.4-slim
docker build --pull --no-cache -t app:patched .
- 逐台核对服务器、构建机、CI 镜像里的 Node 版本;Docker 基础镜像自带一份运行时,需重建而非只改依赖。
- Debian/Ubuntu 包链接系统 libbrotli,不在 Node 内置副本内,须等发行版 brotli 包更新;截至 10 月 21 日 Debian 安全跟踪器尚无该 CVE 条目。
- 20.x 及更早已 EOL,必须迁移到受支持分支,不存在补丁。
- 同批还更新根证书(NSS 3.131.1)剔除 eMudhra 中间 CA 受影响链,一次升级可同时解决证书侧问题。