TL;DR
Google 开发的广泛使用的压缩库 Brotli 曝出高危漏洞 CVE-2026-111497。该漏洞最初由 Node.js 于 10 月 21 日披露,被称为“Node2Shell”,随后 Python、C++、Bun、Envoy 等多个主流语言及 HTTP 服务应用确认受影响。

攻击者可通过发送精心构造的 Brotli 数据导致内存泄露或执行任意代码。CVSS v4.0 评分高达 9.2(关键)。虽然根源问题早在今年 2 月已在 Brotli 源代码中修复,但当时未被认定为安全漏洞,导致下游依赖未及时更新补丁。
最新动态:截至更新时间,libbrotli、Python、C++、Node.js、Bun、Envoy 等已发布补丁。Apache 和 Nginx 默认不解码 Brotli,因此未受直接影响。建议立即检查依赖项并升级至修复版本;若无法升级,建议在补丁可用前禁用 Brotli 解码功能。
Brotli 与 CVE-2026-111497 概述
Brotli 是由 Google 开发的一种无损压缩算法和数据格式,广泛用于 HTTP 传输中以压缩 HTML、CSS 和 JavaScript 等内容。其核心机制是通过缩小数据传输规模来提升效率,接收端软件再将其解压以恢复原始数据。
CVE-2026-111497 是存在于 Google Brotli 解码器中的一个超限写入漏洞,影响所有平台上的 1.0.3 至 1.2.0 版本。远程未经认证的攻击者可利用此漏洞,通过发送恶意构造的 Brotli 压缩流来破坏内存、泄露敏感数据、导致进程崩溃,甚至可能执行任意代码。
技术原理上,该 Bug 导致 Brotli 解码器在应当拒绝数据时继续接受更多字节,从而溢出小型工作缓冲区并损坏程序内存。攻击者可利用这种内存损伤来控制运行内容。这意味着恶意客户端可接管未修补的服务器,而恶意服务器也可接管接受压缩响应的未修补客户端。
受影响范围与技术细节
该漏洞的核心缺陷位于 DecodeBlockTypeAndLength 函数中,该函数处理区块切换(即 Brotli 流改变 Huffman 树的时刻)。在易受攻击的版本中,该函数返回简单的布尔值,其中 BROTLI_FALSE 既可能表示“流有缺陷”,也可能表示“需要更多输入”。调用者无法区分这两种状态,且在快速路径上解码器完全丢弃了返回值。
精心设计的流可以声明单一区块类型并耗尽长度,迫使一个无法成功的切换。此时解码器要么报告需要更多输入,要么继续解码已有的区块状态,后者导致了越界写入。上游修复(google/brotli commit 0ed4268)使函数返回错误代码并新增 BROTLI_DECODER_ERROR_FORMAT_BLOCK_SWITCH (-17),在遇到格式错误时停止解码。
OSM 对 Brotli 1.2.0 和 1.2.1 源码进行差异对比发现,两者仅在版本突破和解码器变化方面有所不同。使用 AddressSanitizer 测试表明,1.2.0 版本在处理约 23 MB 的恶意流时会持续报告需要更多输入而不终止,而 1.2.1 版本每次都能正确拒绝并报错 -17。
Python 生态中的具体影响
Python 受到同一底层 Brotli 解码器漏洞的影响。两个主要的 PyPI 包 Brotli(月下载量达 8280 万次)和 brotlicffi 编译了相同的易受攻击代码。官方 GitHub 公告已发布,但截至 10 月 23 日,咨询数据库尚未将 CVE 映射到 PyPI 包,导致 pip-audit、Dependabot 和 Safety 暂时无法标记这些易受攻击的版本。
如果任何 Python 环境中安装了 Brotli 1.2.0 或更早版本,或 brotlicffi 1.2.0.x,即处于风险之中。常见的 HTTP 客户端如 requests、httpx、aiohttp 以及爬虫框架 Scrapy 在检测到这些包存在时会自动加载并使用它们解码响应。即使应用程序代码中没有显式导入 Brotli,只要安装了相关依赖,攻击者仍可通过发送恶意 Brotli 响应或请求体来触发漏洞。
攻击路径主要有两条:
- 出站请求:应用程序从攻击者控制的服务器获取 Brotli 响应(例如通过 Webhook、URL 预览或爬虫功能)。
- 入站请求:框架或中间件解码带有
Content-Encoding: br的请求体。
修补方案与版本对照
针对 CVE-2026-111497,各主要平台和库需更新至以下修复版本:
| 项目/组件 | 补丁状态 | 固定版本 | 备注 |
|---|---|---|---|
| Node.js | 可用 | 22.23.4, 24.22.1, 26.12.1 | 建议使用支持的最新发布线版本。 |
| Bun | 可用 | 1.4.4 | 包含 Brotli 1.2.1。 |
| Envoy | 可用 | 1.40.0, 1.39.3, 1.38.6, 1.37.8 | 1.36.12 也包含修复,但 1.36 分支不再支持,建议迁移至支持分支。 |
| Istio | 可用 | 1.29.9, 1.30.6, 1.31.2 | 1.29 分支已进入生命周期结束阶段,建议升级。 |
| Google Brotli (上游) | 可用 | 1.0.10, 1.1.1, 1.2.1 | 根据所用库分支选择对应修复版本。 |
| Native Brotli / libbrotli | 可用 | ≥ 1.2.1 | 旧版分支请使用经过修补的 1.0.10 或 1.1.1。 |
| Python 包 | 可用 | Brotli ≥ 1.2.1 brotlicffi ≥ 1.2.1.0 |
无论安装位置如何,均需升级。 |
| curl / libcurl | 可用 | 依赖更新至 1.2.1 | 静态链接或捆绑副本需重新构建应用程序。 |
对于其他 HTTP 服务器、反向代理、API 网关及客户端,需更新其使用的运行时或 Brotli 库。若产品捆绑了 Brotli,请安装明确解决此 CVE 问题的供应商版本。更新后需重建容器镜像、重新部署服务并验证工作负载是否使用已修补组件。
临时缓解措施
在完成全面升级之前,可采取以下措施减少暴露面:
- Python 应用:若 Brotli 为可选依赖,可从环境中卸载
Brotli和brotlicffi,移除如httpx[brotli]等额外功能依赖,并重建依赖锁。注意:这不会移除与其他运行时捆绑的独立 Brotli 解码器,且可能导致部分服务器返回无法读取的响应。 - 入站 HTTP 请求:在反向代理、负载均衡器或中间件中,拒绝包含
br内容编码的请求,确保在易受攻击的解码器处理主体之前拦截。 - 出站 HTTP 请求:从 Accept-Encoding 列表中删除
br。但在自动化机身处理前禁用解码更为关键,因为仅改变 Accept-Encoding 不足以防御,恶意服务器仍可发送 Brotli 响应,而 urllib3 会根据响应头自动选择解码器。
时间线与背景
OpenAI 顾问指出,该漏洞实际上在 2 月份已被发现。当时 Brotli 源代码中的根本原因已被修复,但由于未被视为安全问题,并未引发广泛的补丁分发。直到 10 月 21 日 Node.js 公布 CVE-2026-111497 后,社区才意识到其严重性。次日,Python 发布了相应的安全更新。目前尚不清楚是否有野外利用案例,但鉴于其 CVSS 9.2 的高危评级及广泛的下游集成度,建议视为紧急事项处理。





