2026 年 10 月 21 日,Node.js 官方发布安全更新,一次性修复 10 个漏洞,其中 4 个高危,最严重的是 Brotli 解码器越界写入,可导致远程代码执行(RCE)。修复版本为 26.12.1、24.22.1、22.23.4,覆盖当前全部三条活跃支持线。本文整理全部 CVE 细节、受影响版本、升级命令与特殊场景(快照 / SEA / Permission Model)的注意事项。
一、修复版本:先对号入座
本次更新覆盖 26.x、24.x、22.x 三条release线,各线修复版本如下。EOL 版本(18.x 及更早)不受支持,没有补丁,只能升级。
| 发布线 | 修复版本 | 最高严重级别 | 说明 |
|---|---|---|---|
| Node.js 26.x | 26.12.1 | High | 当前 Current 线,独享 2 个 Low 修复 |
| Node.js 24.x | 24.22.1 | High | Active LTS |
| Node.js 22.x | 22.23.4 | High | LTS 'Jod'(维护模式) |
二、高危漏洞(High):4 个
CVE-2026-111497:Brotli 解码器越界写入(RCE)
本次最严重的漏洞。Brotli 解码器存在越界写入,应用在解压攻击者可控的 Brotli 数据时可能被利用,官方定性为可导致远程代码执行。影响 26.x / 24.x / 22.x 全部三条线。
- 触发场景:HTTP 响应解压(
Accept-Encoding: br)、文件解压、任何把外部数据喂给 Brotli 解码的路径。 - 修复方式:cherry-pick 上游 Brotli 修复提交(
0ed4268a)。 - 该漏洞由 Matteo Collina 报告,修复由 Brotli 上游作者 Evgenii Kliuchnikov 完成。
CVE-2026-105482:dns.resolve 截断含 NUL 字符的名称
dns.resolve 系列函数在处理包含 NUL 字节(\0) 的主机名时会截断名称,导致实际解析的域名与用户传入的不一致。攻击者可借此让 api.evil.com\0 benign.com 这类输入绕过基于域名的校验。影响全部三条线,现已对 resolve 输入做 NUL 字节校验。
CVE-2026-105483:全角数字书写 IP 绕过 TLS 主机名验证
当 IP 地址用全角数字(如 192.168.1.1)书写时,TLS 客户端不会把它识别为 IP,证书校验回落到 DNS 名称比对,于是一张签给域名的证书可以用来认证指向 IP 端点的连接。影响 26.x / 24.x(22.x 不受此条影响,但有同类问题 CVE-2026-106069)。
CVE-2026-106069:主机名宽松解析为 IP 时绕过 TLS 主机名验证
与上一条同一模式:主机名被宽松地解析成 IP 地址时,证书主机名校验可被绕过。影响全部三条线。修复方式是 tls 拒绝非规范 IP 地址(reject non-canonical IP addresses)。
三、中危漏洞(Medium):3 个
| CVE 编号 | 问题 | 影响 |
|---|---|---|
| CVE-2026-105481 | Keep-alive 套接字会处理请求发送前就写入的响应,破坏 HTTP 请求-响应配对语义 | 全部三条线 |
| CVE-2026-106072 | 非规范 IPv4 主机名证书验证不当,允许证书中的 DNS SAN 认证 IP 端点 | 全部三条线 |
| CVE-2026-106074 | crypto.randomUUID() / randomInt() 的熵缓存被写入用户态启动快照和 SEA(单可执行应用),从快照启动的进程会重复产生相同随机值 | 全部三条线(仅快照 / SEA 用户) |
--build-snapshot 或单可执行应用分发,务必重建产物。四、低危漏洞(Low):3 个
| CVE 编号 | 问题 | 影响 |
|---|---|---|
| CVE-2026-106073 | 通过 fs.realpathSync 绕过 Permission Model(权限模型) | 全部三条线 |
| CVE-2026-106071 | Permission Model 通过通配符 radix 查找过度授权文件系统访问 | 仅 26.x |
| CVE-2026-106070 | ZipFile 在 ZIP 头验证失败后返回攻击者可控的前缀字节 | 仅 26.x |
依赖 Permission Model(--permission 启动参数)做沙箱隔离的应用,这三条都属于"沙箱被绕过"级别的问题,建议把升级优先级提到与高危一致。
五、附带更新:eMudhra CA 证书吊销
本次发布还处理了 eMudhra CA 密钥泄露事件。Mozilla 在 10 月 17 日收到报告:eMudhra 8 张中间证书的私钥已泄露,攻击者可能借此签发任意站点的伪造 HTTPS 证书。
- 三个发布线的根证书全部更新到 NSS 3.131.1(移除签发受影响中间证书的根)。
- TLS 链中出现被封锁的公钥时直接拒绝连接。
- 如果业务依赖 eMudhra 签发的证书链,需要尽快换证书,否则升级后握手会失败。
依赖库同步升级:c-ares 1.34.9(全部线)、OpenSSL 3.5.9(24.x / 22.x)、SQLite 3.53.4(22.x)、undici 6.29.1(22.x 线,三条线均有更新)。
六、先确认当前版本
node -v
# 确认生产进程实际使用的二进制(PM2 / systemd / Docker 各查一遍)
pm2 env 0 | grep node_path
systemctl cat your-app | grep ExecStart
# 容器环境直接看镜像标签
docker exec your-container node -v
七、升级操作
方式 1:nvm(开发机 / 单机部署)
# 按当前发布线打补丁(推荐:小版本升级,风险最低)
nvm install 22.23.4
nvm alias default 22.23.4
# 或直接跨到 Active LTS
nvm install 24.22.1
nvm alias default 24.22.1
# 重装全局包后验证
node -v
方式 2:Ubuntu / Debian(NodeSource 源)
sudo apt update
sudo apt install --only-upgrade nodejs
# 确认补丁版本
node -v
方式 3:Docker(官方镜像)
# 旧
FROM node:22.23.3-slim
# 新(拉取修复版)
FROM node:22.23.4-slim
# 或
FROM node:24.22.1-slim
docker compose build --pull
docker compose up -d
# 验证容器内版本
docker exec your-app node -v
node:22-slim 这种浮动标签,执行 docker compose build --pull 即可拉到修复版;写死具体版本的镜像需要改标签重建。方式 4:PM2 集群滚动重启
# 升级 Node 后,让 PM2 用新二进制重启全部进程
pm2 update
pm2 reload all
# 确认运行中的 Node 版本
pm2 env 0 | grep -i version
八、无法立即升级时的针对性缓解
官方未提供完整缓解方案,但以下措施能收窄攻击面,不能替代升级:
- Brotli RCE(CVE-2026-111497):在反代层(Nginx)移除
br解压支持,应用内避免解压不可信来源的 Brotli 数据;仅保留 gzip。 - TLS 主机名绕过(CVE-2026-105483 / 106069 / 106072):出站请求白名单化,固定目标 IP 与 SNI;避免把用户可控的主机名直接交给
https.request。 - dns.resolve NUL 截断(CVE-2026-105482):在调用
dns.resolve*前自行校验主机名(拒绝含\0的输入)。 - 随机值重复(CVE-2026-106074):暂停分发新快照 / SEA 产物;安全敏感的 UUID 生成改用
crypto.randomBytes(16)手动拼装(不经过缓存路径),并做好版本标注。 - Permission Model 绕过(CVE-2026-106073 / 106071):不要把 Permission Model 当作唯一防线,叠加操作系统级沙箱(容器、
seccomp、只读挂载)。
九、升级后验证
node -v
node -p "process.versions"
# 关键依赖版本核对(OpenSSL / c-ares)
node -p "process.versions.openssl"
node -p "process.versions.cares"
# 快速功能冒烟:TLS、DNS、crypto
node -e "require('https').get('https://nodejs.org', r => console.log('tls ok', r.statusCode))"
node -e "require('dns').resolve('nodejs.org', (e,a) => console.log(e ? 'dns fail' : 'dns ok'))"
node -e "console.log(require('crypto').randomUUID())"
十、行动建议
| 当前版本 | 立即动作 | 后续规划 |
|---|---|---|
| 26.x | 升到 26.12.1 | 跟随 Current 线补丁节奏 |
| 24.x | 升到 24.22.1 | Active LTS,生产推荐长期停留 |
| 22.x | 升到 22.23.4 | 维护模式 LTS,规划迁往 24.x |
| 20.x 及更早 | 无补丁,立即迁移 | 直接升到 24.22.1 / 26.12.1 |
这次 10 个漏洞里有 3 个都指向同一类问题:TLS 校验对"非规范写法"的 IP 失明。
补丁可以等一个维护窗口,但暴露在公网的 Brotli 解压和快照分发,今晚就该处理。