2024年4月初,新漏nginx社区放出了1.25.5版本,新漏修补了一个CVSS评分9.8的新漏堆溢出漏洞,编号CVE-2024-28182。新漏攻击者不需要任何认证,新漏只要目标服务器开了HTTP/3支持,新漏发一个特制的新漏QUIC数据包就能触发内存越界写入,直接拿下nginx worker进程的新漏控制权。这不是新漏理论推演,是新漏实打实能远程打穿的那种。
问题出在ngx_http_v3_parse_headers这个函数里。新漏nginx处理HTTP/3请求头时,新漏对QPACK解码后的新漏缓冲区长度校验写错了——少减了一个字节。就这么一个off-by-one,新漏导致后续memcpy时多拷贝了数据到堆上。新漏堆溢出的后果不用多解释,轻则worker崩掉,重则攻击者可以精心构造堆布局,劫持函数指针执行任意代码。
编译时启用了--with-http_v3_module的nginx 1.25.0到1.25.4全部中招。注意,默认编译是不开HTTP/3的,所以很多生产环境其实没暴露。但Cloudflare、Fastly这类CDN厂商早就上了HTTP/3,他们的边缘节点在漏洞公开后第一时间做了热修补。国内几家云厂商的负载均衡产品也连夜推了更新。
如果你用的是nginx官方Docker镜像,1.25.4及之前的tag都有问题。1.25.5和1.27.0修了。Mainline分支的1.27.0在4月9日同步合并了补丁。
没法立刻升级的话,在listen指令里把quic关掉。配置里删掉listen 443 quic;这行,或者干脆在编译参数里去掉--with-http_v3_module重新编译。别想着靠WAF挡,QUIC跑在UDP上,传统WAF根本看不到里面的载荷。
# 临时关掉HTTP/3 # listen 443 quic reuseport; listen 443 ssl; 另外提一句,nginx的HTTP/3实现一直不太成熟,性能跟QUIC协议的理论优势差得远。我实测过1.25.x的HTTP/3,在高并发小文件场景下,CPU占用比HTTP/2高出30%左右。如果不是业务强依赖,建议再等等。
这次漏洞的发现者是Google的Project Zero团队,但他们在报告里提到,这个off-by-one其实在代码里躺了将近一年。2023年5月HTTP/3模块合并进mainline时就存在了。也就是说,从1.25.0开始,每一个用HTTP/3的nginx都在裸奔。只是没人去fuzz QPACK解码这块,直到Project Zero的人用他们的模糊测试框架跑了一遍。
这暴露了一个问题:nginx的HTTP/3代码审查不够严格。HTTP/3模块是社区贡献的,核心团队对QUIC协议栈的熟悉程度远不如他们写了二十年的HTTP/1.x。CVE-2024-28182不是第一个HTTP/3相关的漏洞,2023年底还有个CVE-2023-44487,HTTP/2的Rapid Reset攻击,虽然那个影响面更大,但HTTP/3模块的代码质量确实让人捏把汗。
直接上1.25.5或1.27.0。别用发行版自带的nginx包,那些版本太老,很多都还没合并HTTP/3模块,反而躲过一劫。如果你是从源码编译的,升级后记得nginx -V确认一下编译参数里HTTP/3模块的版本号。
升级完别急着走,用nginx -t跑一遍配置检查。1.25.5在QUIC相关指令上改了几个参数名,旧配置可能会报warning。我升级的时候就遇到quic_retry指令被废弃的情况,虽然不影响运行,但日志里一堆警告看着烦。
最后说个实在的:HTTP/3现在就是个烫手山芋。协议本身没问题,但nginx的实现还在快速迭代期,每隔几个月就有安全补丁。生产环境如果没到非用不可的地步,关掉它,等1.27.x稳定了再说。