安全公司FoxIO公开了可用的概念验证代码:一个未登录的远程攻击者,只靠一条连接,就能让大量HTTP/3服务器崩溃。

打开网易新闻 查看精彩图片

手法并不复杂。攻击者发送一小批压缩过的HTTP头,这批数据在服务器内存里展开成远大于原始体积的头部集合,服务器被迫占用比收到的数据多出数千倍的内存,默认配置的服务器足以被直接耗尽内存。

FoxIO在测试的十个HTTP/3协议栈中,有七个存在同一类缺陷。共同原因指向QPACK——HTTP/3用来压缩请求头的方案,重复出现的字段以短代码传输,而不是每次都传完整文本。

按设计,服务器应当对解压后的头部大小设上限。受影响的协议栈把上限设在了链路上到达的压缩批次上,却没有限制解压结果,或者限制施加得太晚。结果是一个请求就能展开成数十万个头部条目,全部留在服务器内存里。

影响面广,是因为这些协议栈位于常见软件之下:

  • quic-go 是 Caddy、Traefik 和 cloudflared 背后的 Go 库;
  • lsquic 是 LiteSpeed 的库,用于 LiteSpeed Web Server 和 OpenLiteSpeed;
  • Bun 的 HTTP/3 服务器跑在 lsquic 上。

攻击者不需要账号,也不需要特殊权限。HTTP/3 跑在 UDP 上,请求在大部分常规过滤生效之前就已抵达服务器。

放大倍数因协议栈而异,以下为 FoxIO 在默认设置下的实测。在 quic-go 上,1 MB 的压缩批次解压出约 16 万个头部字段,请求中留下约 15 MB,约为发送字节数的 17 倍;quic-go 自己的公告给出的可能放大倍数约为 50 倍。

第二种方法把比例推得更高:攻击者先存入一个约 4 KB 的头部条目,再用一字节的引用指向它数千次,服务器每次引用都重建完整条目。FoxIO 在 Bun 上测到约 4000 倍,在 lsquic 上测到 600 到 1800 倍。

Bun 的情况最糟。其 HTTP/3 服务器被 Bun 文档称为实验性功能,底层用 lsquic,但把限制头部内存的那部分换成了自己的代码——逐个头检查,从不检查累计总量。FoxIO 发现,解压后的头部一旦超过 2 GB,这段代码里的一个大小计数器会溢出归零,服务器随即进入一个永远出不来的循环。

FoxIO 报告称,一条链路上约 516 KB 的流,就能让服务器卡在 100% CPU,无法恢复,新请求全部被挡住。缺失的累计总量正是溢出得以触达的原因;lsquic 自带的 64 KB 上限挡住了这条路。

Wireshark 属于另一类问题。它的缺陷会让 HTTP/3 解析器崩溃——当 Wireshark 用密钥日志文件解密流量,或打开含有解密密钥的抓包文件时触发。它不是攻击者能通过网络访问的服务器。Wireshark 表示“未发现该问题的任何利用”。

这些缺陷只造成拒绝服务,没有数据被窃取或代码执行的证据,也没有公开的野外攻击报告。截至 2026 年 10 月 22 日,quic-go、Cloudflare quiche、lsquic 和 Wireshark 已发布修复;Bun、h3 Rust 库和 aioquic 在披露时仍未修补。

FoxIO 将 IIS、Envoy、ngtcp2/nghttp3 和 Google 的 quiche 列为不受影响,原因是它们在解码过程中就对解压后的头部设限,而不是等到解码之后。

运维方的处置路径:升级到上述已修复版本。对尚无修复的协议栈,FoxIO 给出临时措施——Bun 上不要暴露 HTTP/3 服务器;mitmproxy 上通过 --set http3=false 关闭 HTTP/3;h3 Rust 库用 max_field_section_size 设一个合理上限。

lsquic 的修复于 2026 年 7 月 16 日发布,限制服务器每条流持有的解压头部集合数量,默认为一个。FoxIO 称这项工作始于 Gal Bar Nahum 对“MadeYouReset”的研究——那是一种针对 HTTP/2 的拒绝服务手法,其提出的问题是:HTTP/3 的头部压缩是否存在类似弱点。