Node2Shell 升级为 HTTP2Shell:Brotli 漏洞波及众多 HTTP 库和应用
坐稳了。
⚠️ Brotli 是 Google 开发的一款广泛使用的压缩库。周三(10月21日),NodeJS 披露了名为“node2shell”的 CVE-2026-111497 漏洞:解析攻击者可控的 Brotli 数据的 Node.js 进程可能发生内存泄漏或被执行任意代码。周四,Python 官方宣布 Python 包同样受此漏洞影响。
周五(10月23日),该漏洞被发现在其他使用 HTTP 的主要语言和服务应用中同样存在,且相关补丁尚未完全发布。
请检查你的库依赖中是否包含 Brotli 解码功能。保持警惕,关注更广泛的公告,并尽快准备升级。如果受影响的库或应用暂无可用补丁,建议在补丁推出前禁用 Brotli 解码。
更新(太平洋时间 4:12 PM): 已为、、、、、 及更多项目提供补丁。Apache 和 Nginx 默认不解码 brotli。
OpenAI 分享说 在二月。虽然根本原因的问题当时已在 Brotli 源代码中修复,但当时并未意识到其衍生出的安全漏洞。OpenAI 的咨询 .

Brotli 是 Google 开发的一种无损压缩算法和数据格式,旨在缩小数据体积以便存储或通过网络传输,软件随后将其解包以恢复原始数据。它广泛用于 HTTP 压缩,以压缩 HTML、CSS 和 JavaScript 等 Web 内容。
CVE-2026-111497 是什么?
CVE-2026-111497 是 Google Brotli 解码器中的一个越界写入漏洞,影响所有平台上 1.0.3 至 1.2.0 版本。这正是几天前公布的 Node2Shell 背后的同一个 Brotli 解码器缺陷。远程未认证攻击者可以通过发送精心构造的 Brotli 压缩流来破坏内存、泄露敏感数据、导致进程崩溃,甚至可能执行任意代码。该漏洞 CVSS v4.0 评分为 9.2(严重),Node.js 因其内置 Brotli 库而受到影响。
这个 bug 导致 Brotli 解码器在应当拒绝数据时继续接收更多字节。这些字节可能溢出一个小型工作缓冲区,破坏程序内存。攻击者可以利用这种破坏来控制程序的执行,比如运行自己的代码。
OpenAI 于今年 2 月发现了这个问题,并将其报告为双向可利用的未认证远程代码执行漏洞:恶意客户端可以接管未打补丁的服务器,恶意服务器也可以接管接受压缩响应的未打补丁客户端。
根本原因已于 2 月在 Brotli 源代码中修复,但当时未被认定为安全问题,直到现在才有包含修复的版本发布。这意味着所有内置 Brotli 的项目都得自行发布更新。
只要任何环境安装了 Brotli 1.2.0 及更早版本,或 brotlicffi 1.2.0.x,你就有风险,因为 requests、httpx、aiohttp 等 HTTP 客户端在检测到这些包时会自动加载它们。请升级到 Brotli 1.2.1 或 brotlicffi 1.2.1.0,并重新构建包含它们的容器镜像。截至 10 月 23 日,各漏洞通告数据库尚未将该 CVE 关联到这两个 PyPI 包,因此 pip-audit、Dependabot 和 Safety 暂时还无法标记出受影响的版本。
你可以在 Aikido Intel 中查看我们跟踪的相关信息。
至于不受影响的软件,Apache 的标准 mod_brotli 并不解码 Brotli。
如何修复 HTTP2Shell CVE-2026-111497
针对 CVE-2026-111497,请更新受影响的运行时或 Brotli 库:
- Node.js: 升级到 22.23.4、24.22.1 或 26.12.1,或对应发布线中更新的受支持版本。
- 原生 Brotli / libbrotli: 升级到 1.2.1 或更高版本。对于较旧的发布线,请使用修复后的 1.0.10 或 1.1.1。
- Python 包: 在任何安装位置将 Brotli 升级到 1.2.1 或更高版本,将 brotlicffi 升级到 1.2.1.0 或更高版本。
- curl / libcurl: 将其 Brotli 依赖项更新为 1.2.1、修复后的旧版本或厂商提供的安全修复包。若使用了捆绑或静态链接副本,需要重新构建应用。
- Bun: 升级到 1.4.4 或更高版本。重新编译任何捆绑了 Bun 的可执行文件。
- 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 分支已终止支持。
- 操作系统包: 安装厂商的安全更新。厂商可能会在不改变上游版本号的情况下向后移植修复。
- 其他 HTTP 服务器、反向代理、API 网关和 HTTP 客户端: 更新其使用的受影响运行时或 Brotli 库。如果 Brotli 被捆绑在产品中,请安装明确提及解决此 CVE 的产品厂商版本。对于托管服务,请与提供商确认修复情况。
更新依赖锁定文件,重新构建受影响的应用程序和容器镜像,重新部署并重启服务。验证正在运行的工作负载使用了修复后的组件。
| 项目 | 补丁状态 | 已修复版本 | 备注 |
|---|---|---|---|
| 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 | 请选择对应库分支的已修复版本。 |
暂时无法升级时的应对措施
在准备升级期间,这些临时措施可降低风险敞口:
- Python 应用:若 Brotli 支持为可选功能,请从受影响的卸载环境中移除 Brotli 和 brotlicffi。清除 httpx[brotli] 等依赖附加项及其他会导致重新安装的依赖项,然后重新生成依赖锁文件并重建或重启工作负载。即使移除这些可选包,HTTPX、Requests 和 urllib3 仍可保留 gzip 和 deflate 支持。不过,若服务器仍强制发送 Brotli 压缩数据,可能导致响应无法解析或应用报错;自动回退机制并不保证生效。
- 卸载这两个 Python 包并重启工作负载,仅移除由这些包提供的入站和出站数据解码路径。它不会移除嵌入在其他运行时、库或产品中的独立 Brotli 解码器。
- 入站 HTTP 请求:在反向代理、负载均衡器或应用中间件中,拒绝 Content-Encoding 包含 br 的请求。此检查须在任何易受影响的解码器处理请求体之前完成。匹配 br 时应忽略大小写,包括在编码列表中的情况。
- 出站 HTTP 请求:从 Accept-Encoding 中移除 br。同时禁用 Brotli 响应解码,或在解码开始前拒绝 Content-Encoding 包含 br 的响应。务必确保此检查发生在自动处理请求体之前;在客户端下载并解码响应后再进行检查为时已晚。
仅修改 Accept-Encoding 不足以消除风险:恶意服务器可无视客户端声明而发送 Brotli 响应,且 urllib3 是根据响应中的 Content-Encoding 头选择解码器的。
请保持这些控制措施生效,直至受影响的组件完成补丁更新并通过验证。随着供应商确认更多受影响的组件或攻击路径,需持续审查防护覆盖范围。
Aikido 如何应对 CVE-2026-111497
Aikido 会扫描你仓库、容器镜像和依赖中存在漏洞的 Brotli 与 brotlicffi 版本,包括作为传递依赖引入的情况。你的面板会显示哪些服务仍在运行有漏洞的版本,方便你优先升级那些调用外部服务器或接受压缩请求体的服务。
升级完成后,Aikido 会检查该问题是否已消除。
时间线
Brotli 是 Google 开发的广泛使用的压缩库。10 月 22 日(周三),NodeJS 披露了 CVE-2026-111497,代号“node2shell”:Node.js 进程在解压攻击者可控的 Brotli 数据时,可能被诱导泄露内存或执行任意代码。只要你的应用或某个库会解压恶意 Brotli 数据(例如内置的 fetch()、body-parser),就会暴露在风险之下。
第二天,Python 发布了修复同一漏洞的安全更新,说明 Python 包同样受 CVE-2026-111497 影响。鉴于该库在下游的集成范围之广,此 Brotli 漏洞可能波及更多语言和服务应用。原来 OpenAI 早在今年二月就发现了这个问题。
CVE-2026-111497 的技术细节
漏洞位于DecodeBlockTypeAndLength()中,该函数负责处理块切换,即 Brotli 流更换所用 Huffman 树的位置。在有漏洞的版本里,这个函数只返回一个普通布尔值,BROTLI_FALSE 既可能表示“这个流已损坏”,也可能表示“我还需要更多输入”。调用方无法区分这两种情况,而在快速路径上,解码器甚至完全忽略返回值。
一个精心构造的流可以声明一个块类型,然后耗尽该块的长度,从而触发一次注定失败的切换。此时解码器要么对一个已经完整的流报告“需要更多输入”,要么继续沿用原有的块状态解码。后一种路径就会导致越界写入。
上游修复 google/brotli 提交 0ed4268 让该函数返回错误码,并新增错误 BROTLI_DECODER_ERROR_FORMAT_BLOCK_SWITCH(-17)。如今,无论是安全路径还是快速路径,解码遇到格式错误都会立即停止。OSM 对比了 Brotli 1.2.0 和 1.2.1 的源码发行版,发现 1.2.1 与 1.2.0 的差异仅在于版本号更新以及该提交中引入的解码器修改。
Python 库中的 Brotli 漏洞(CVE-2026-111497)
Node2Shell(CVE-2026-111497)背后的 Brotli 缺陷同样影响 Python。Brotli 和 brotlicffi 这两个 PyPI 包编译了与 Node.js 内置版本相同的存在漏洞的 Brotli 解码器。GitHub 已发布官方安全公告。Brotli 包每月下载量高达 8280 万。
如果你的 Python 环境中安装了 Brotli 1.2.0 或更早版本,或 brotlicffi 1.2.0.x 版本,你就受到影响。requests 和 httpx 等流行 HTTP 客户端会在这些包存在时自动加载它们。一些包(如 Scrapy)会自动将 Brotli 作为依赖项安装,而另一些包则需要显式声明。攻击者只需向你的应用发起请求并发送恶意的 Brotli 响应,或向你的应用发送经 Brotli 压缩的请求体,即可触发有漏洞的解码器。这意味着即使应用自身的代码从未导入过 Brotli,也可能因此暴露风险。由于这是常见的传递依赖项,请务必检查你的系统。
要修复此问题,请升级到已修补的版本:
- Brotli -> 1.2.1
- brotlicffi -> 1.2.1.0
这两个修复版本的发布说明均未提及该 CVE。截至 10 月 23 日,安全公告数据库尚未将其映射到这两个 PyPI 包,因此 pip-audit、Dependabot 和 Safety 不会标记这些版本。
谁受 Python 中 CVE-2026-111497 影响?
如果你的任何 Python 环境安装了以下任一包,你就受到影响:
| 包 | 受影响版本 | 修复版本 |
|---|---|---|
| Brotli (PyPI) | 1.2.0 及更早版本 | 1.2.1 |
| brotlicffi (PyPI) | 1.2.0.x | 1.2.1.0 |
你的代码不需要直接导入这两个包。这些 HTTP 客户端会发出 Accept-Encoding: br 请求头,并自动解码 Brotli 响应:
- urllib3(以及基于它的 requests),前提是安装了 Brotli 或 brotlicffi
- 带 brotli 扩展的 httpx
- 安装了 Brotli 的 aiohttp
- Scrapy,以及基于上述客户端构建的任何工具
攻击者数据可以通过两条路径到达解码器:
- 出站请求。你的应用从攻击者控制的服务器获取 Brotli 响应,例如通过 webhook 推送、URL 预览、爬虫或“抓取此 URL”等功能。
- 入站请求。你的框架或中间件解码带有 Content-Encoding: br 的请求体,这在 Python 中相当于 Node.js 中 Express 5 的案例。
如何修复 Python 中的 CVE-2026-111497
修复方法是升级包,共分四步:
- 使用 pip install -U "Brotli>=1.2.1" 或 pip install -U "brotlicffi>=1.2.1.0" 升级已安装的相应包。如果你使用 Poetry、uv 或 pip-tools 的锁定文件,请更新约束并重新生成锁定文件。
- 重建容器镜像和捆绑了任一包的 wheel。基于易受攻击版本构建的镜像在重建前仍然保持易受攻击状态。
- 检查所有运行环境,包括笔记本电脑、CI runner、服务器和容器。许多项目通过 HTTP 客户端的扩展引入了 Brotli,因此请检查完整的依赖树。
- 目前依赖手动检查。在建议数据库将该 CVE 映射到 PyPI 包之前,pip-audit、Dependabot 和 Safety 不会报告此问题。
如果你的 Python Brotli 绑定来自 Linux 发行版包而非 PyPI,则修复将通过你的发行版提供,因此也请检查其安全公告。
什么是 Python Brotli 漏洞(CVE-2026-111497)?
Python Brotli 漏洞指的是 CVE-2026-111497,即< a href="https://www.aikido.dev/blog/node2shell-nodejs-brotli-rce-cve-2026-111497">Node2Shell 所描述的 Brotli 解码器缺陷在 PyPI 上的 Python 包中受影响。该 CVE 记录将 CWE-252(未检查的返回值)与 CWE-787(越界写入)关联。
CVE-2026-111497 对 Python 的严重程度如何,是否正在被利用?
CVE 记录将此漏洞评为 CVSS 4.0 评分 9.2,Node.js 官方也将其定为高危。OSM 用 AddressSanitizer 构建了 Brotli 1.2.0 和 1.2.1,并把一段特制数据流分别喂给两个版本。结果显示,1.2.0 无论是收到完整的数据流还是逐字节的小分片,都会消耗掉约 23 MB 的全部数据,并持续报告还需要更多输入;而 1.2.1 则每次都以错误码 -17 拒绝该数据流。
OSM 没有在 Python 扩展中进一步尝试内存破坏或代码执行。解码器代码与研究人员利用攻击未修改的 Node.js 24.22.0 构建时的代码相同,Imperva 等机构此前已有报道。据 The Hacker News 报道,截至 10 月 22 日,Node.js 方面尚未发现实际攻击案例。
不过仍应尽快处理。这是一个处理不可信网络输入组件中的内存安全漏洞,而修复只需常规的版本升级。调用外部服务器或接收压缩请求体的服务应优先升级。
如何检查你的 Python 应用是否受影响
- 在各环境中用 pip show Brotli brotlicffi 检查已安装版本,对每个容器镜像用 docker run --rm <image> pip show Brotli brotlicffi 检查。
- 查明哪些依赖引入了这些包。运行 pipdeptree -r -p Brotli 查看哪些依赖需要它,并用 grep -i brotli poetry.lock uv.lock requirements*.txt 在锁文件中搜索。
- 列出所有调用你不受控服务器的出站 HTTP 请求,以及任何解码 Content-Encoding: br 请求体的端点。
- 优先升级符合第 3 条的服务,再处理其余。
如果你想在 Python 中复现该漏洞,注意 brotli.decompress() 对任何错误都只抛出通用的 brotli.error: decoder failed,看不到具体的错误码。而用 Decompressor() 增量喂入特制数据流时,1.2.0 版本永远不会结束。
FAQ
哪些版本修复了 Python 中的 CVE-2026-111497?
Brotli 1.2.1 和 brotlicffi 1.2.1.0,以及所有更新的版本。
我的代码需要 import Brotli 才会受影响吗?
不需要,只要安装了该包就受影响。urllib3、requests、httpx 和 aiohttp 在检测到 Brotli 或 brotlicffi 时会自动使用它们,并解码应用所调用的任何服务器返回的 Brotli 响应。
pip-audit 或 Dependabot 会标记这个漏洞吗?
尚无。截至10月23日,CVE 记录、OSV 和 GitHub 安全咨询数据库均未列出这两个 PyPI 包。OSM 正在提交 PYSEC 条目及 PyPI 包映射,以便相关工具能收录这一 GitHub 安全咨询。
有变通方法吗?
卸载 Brotli 和 brotlicffi 可移除存在漏洞的解码器,HTTP 客户端随后会回退至 gzip 和 deflate。在边缘拒绝 Brotli 编码请求可减少入站风险,但无法保护应用自行获取的 Brotli 响应。
分享:https://www.aikido.dev/blog/python-packages-vulnerable-node2shell-brotli-cve-2026-111497
文本链接检查漏洞
立即开始4.7/5受够了误报?试试 Aikido,已有 10 万用户采用。立即开始获取个性化讲解
超过 10 万团队的信赖之选
立即预约扫描应用中真实的 IDOR 和攻击路径超过 10 万团队的信赖之选
开始扫描了解 AI 如何对你的应用进行渗透测试超过 10 万团队的信赖之选
开始测试立即开始相关文章查看全部2026年10月22日•漏洞与威胁Node2Shell:Node.js Brotli 漏洞允许远程代码执行(CVE-2026-111497)
Node.js CVE-2026-111497(Node2Shell)是一个 Brotli 缺陷,可导致远程代码执行。了解受影响方、已修复版本及修复方法。
eMudhra CA 泄露:八把私钥,其中一把密钥竟是 4
八把 eMudhra CA 密钥最多仅需 256 次尝试即可猜测出,其中一把仅仅是数字 4。了解受影响方、为何 curl 落后于浏览器,以及如何修复。
LiteLLM 再次被入侵:1.107.0 版本中发现信息窃取器和 RAT
LiteLLM 1.107.0 包含信息窃取器和 RAT,PyPI 已隔离该包。确认你是否受影响、窃取了哪些信息,以及需要轮换哪些凭证。
# 恶意软件立即实现安全,
快速且免费。
通过单一中心系统保护您的代码、云环境和运行时。
连接代码仓库,即可发现推理代理(reasoning agents)在您的代码库中识别出的问题。