Node.js 22.23.4、24.22.1 和 26.12.1 修复了 CVE-2026-111497,这是一个可能导致 RCE 的 Brotli 解码器溢出。谁暴露了,如何检查,做什么。

10 月 21 日星期三,Node.js 项目发布了所有三个受支持产品线的安全版本: v26.12.1 (当前), v24.22.1 (活跃 LTS,“氪”)和 v22.23.4。他们共同关闭了 10 个 CVE。其中一个比其他九个加起来更重要。
CVE-2026-111497 位于 Node.js 内部附带的 Brotli 解码器中。的 官方咨询 用两句话解释了该错误:“无效的块切换被报告为临时需要更多输入,而不是永久格式错误,因此流解码器不断将输入字节附加到八字节内部缓冲区。”简单来说,格式错误的压缩数据告诉解码器继续等待,等待期间到达的每个字节都被写入微小缓冲区的末尾。
根据 Node.js 的说法,攻击者可以将 Brotli 数据提供给任何可以使用以下命令解压缩的东西 node:zlib 可能会损坏进程内存。结果范围从崩溃、泄漏进程内存到远程代码执行。 Node.js 对其评价很高。奎利斯得分 CVSS 4.0 9.2,严重。 Node.js 没有发布解决方法。升级就是解决办法。

该错误由 OpenAI Codex Security(Khai Tran 和 Sylvie Mayer)报告,并由 Matteo Collina 和 Antoine du Hamel 修复,他们挑选了 Evgenii Kliuchnikov 的上游 Brotli 提交。社交媒体上的研究人员开始将其称为“Node2Shell”。 Node.js 不使用该名称。
仅当不受信任的压缩字节到达解压缩器中的内存错误时,解压缩器中的内存错误才会产生影响。令人不舒服的是这些路径是多么普通。 Node.js 公告没有列出它们;下面的映射来自安全公司 布兰德芬斯 和 阿斯特拉。
可通过以下方式到达 Express 5 express.json()。 它的 body-parser 2.x 解码 br、gzip、deflate 和 zstd 请求主体,因此发送的客户端 Content-Encoding: br 将其有效负载直接传递给易受攻击的解码器。 Express 4 无法通过这种方式访问,因为它的主体解析器会拒绝带有 415 的 Brotli 主体。这是一种罕见的情况,旧框架更安全,并且这不是留在 Node 20 上的理由。

服务器端 fetch() 也是一条路。 每当响应显示时,Node 内置 fetch 背后的 undici 代码就会添加 Brotli 解压缩器 br。获取用户提供的 URL 的服务(链接预览、网络挂钩、抓取工具、图像代理)可能会因将其指向恶意服务器而受到攻击。 Astra 使用 Brotli 压缩和任何解压上传的压缩文件的服务添加 WebSocket 帧。
Qualys 检查了其客户资产中的 330 万个 Node.js 安装,并于 10 月 23 日公布了这些数字。只有约 42,000 个(即 1.2%)使用的是固定版本(如果仅计算 Qualys 可以识别的 310 万个安装版本,则为 1.4%)。另外 130 万安装在受支持的线路上但尚未更新,所有安装的 15% 位于面向互联网的计算机上。这是夸利斯自己的遥测数据,而不是互联网的人口普查,但没有理由认为更广泛的情况更好。

更大的数字是停产版本的 170 万次安装。这些永远不会得到修复。 Node.js 20 于 2026 年 4 月 30 日终止生命周期,奇数行(21、23 和 25)从来都不是长期版本。对于所有这些,唯一的补救措施是主要版本升级,这可能会带来依赖性和本机模块损坏。
运行 node --version 在实际提供流量的运行时内。这意味着生产中的容器映像,而不是您开发的笔记本电脑,也不是您认为正在使用的基本映像标签。然后与这个表进行比较。
| 你跑 | 状态 | 移至 |
|---|---|---|
| 26.x | 目前,将于 10 月 28 日成为 LTS | 26.12.1 |
| 24.x | LTS,26 接管后进入维护阶段 | 24.22.1 |
| 22.x | 维护长期支持 | 22.23.4 |
| 25.x、23.x、21.x | 寿命结束,无法修复 | 24.22.1或26.12.1 |
| 20.x 及以上 | 寿命结束,无法修复 | 至少 22.23.4; 24或26是更好的跳跃 |
相同的版本还刷新了捆绑的依赖项。在 v24.22.1 中,这意味着 OpenSSL 3.5.9、c-ares 1.34.9、undici 7.30.1、NSS 3.131.1 根证书和 2026e 时区数据,因此在推出之前测试任何固定证书行为的内容。

如果您无论如何都计划从 20 或 22 跃升,那么时机会有所帮助。 Node.js 26 于 2026 年 10 月 28 日进入 LTS,并在 2029 年 4 月 30 日之前获得支持,这比登陆 22 并在明年再次这样做购买了更多的跑道。
Node.js 提供的只是补丁,因此权宜之计来自 Qualys,它们减少而不是消除暴露。尽可能停止从不受信任的来源解压 Brotli。剥离或拒绝 Content-Encoding: br 针对反向代理或 WAF 的入站请求,并限制那里的压缩负载大小。对于需要大量获取的服务,限制服务器将调用哪些主机。这些都没有涵盖您未找到的路径,这就是为什么每一个都是升级的桥梁而不是替代品。
Brotli 漏洞使其他漏洞黯然失色,但另外三个漏洞被评为“高”,其中两个漏洞削弱了 TLS 主机名检查。并非每个错误都会影响每一行:
| CVE | 严重性 | 它的作用 | 线路 |
|---|---|---|---|
| CVE-2026-105482 | 高 | dns.resolve 截断包含 NUL 字符的名称 | 26, 24, 22 |
| CVE-2026-105483 | 高 | 当 IP 以全角数字写入时,会绕过 TLS 主机名检查 | 26, 24 |
| CVE-2026-106069 | 高 | 当主机松散解析为 IP 地址时,TLS 主机名检查被绕过 | 26, 24, 22 |
| CVE-2026-105481 | 中等 | 保持活动套接字处理在发送请求之前写入的响应 | 参见咨询 |
| CVE-2026-106072 | 中等 | DNS SAN 可以通过非规范 IPv4 主机名对 IP 端点进行身份验证 | 参见咨询 |
| CVE-2026-106074 | 中等 | crypto.randomUUID() 和 randomInt() 熵缓存保存到启动快照和SEA中 | 参见咨询 |
| CVE-2026-106070 | 低 | ZipFile 在标头检查失败后返回攻击者控制的前缀字节 | 26 |
| CVE-2026-106071 | 低 | 通过通配符查找过度授予权限模型文件系统 | 26 |
| CVE-2026-106073 | 低 | 权限模型绕过 fs.realpathSync | 26, 24, 22 |
如果您发布单个可执行应用程序,那么随机性错误值得再次关注:从同一快照构建的每个副本都可以从相同的缓存熵开始。
截至 2026 年 10 月 23 日 22:00 UTC(布兰德芬斯发布的最新检查)尚未确认。 CISA 的已知被利用漏洞目录当时并未列出 CVE-2026-111497,并且 Astra 报告没有在野利用。 GitHub 上的公开概念验证代码确实会导致未修补的 Node.js 崩溃。远程代码执行尚未解决:一位研究人员表示,他们的团队在身份验证之前复制了该代码,Aikido 报告研究人员在官方 Node.js 24.22.0 映像上运行了代码,尽管“该漏洞并非每次都有效”。
按需崩溃已经是针对任何公开的 Express 5 API 的拒绝服务错误,并且随着时间的推移,漏洞利用很少会变得不那么可靠。这是本月第二次需要紧急修复的运行时,此前 PHP。将升级视为本周的工作,而不是下个季度的工作,并使用 10 月 28 日的 Node 26 LTS 日期作为仍在生命周期结束的任何产品的截止日期。
