事件概述
2026年7月15日,F5/NGINX团队发布安全更新,修复了一个被安全研究员Stan Shaw(代号Cyberstan)披露的致命漏洞CVE-2026-42533。该漏洞存在于nginx脚本引擎的内部表达式评估机制中,允许远程未认证攻击者通过堆缓冲区溢出实现预认证远程代码执行(Pre-Auth RCE)。
更令人震惊的是,这个漏洞从2011年3月21日nginx 0.9.6版本引入map指令的正则表达式支持时就已经存在,潜伏时间长达15年。受影响范围覆盖nginx 0.9.6至1.30.3(stable)/1.31.2(mainline)的所有版本,以及NGINX Plus R33至R36和37.0.0.1至37.0.2.1版本。
技术细节
漏洞根因:两步走评估模型的致命缺陷
nginx的脚本引擎在编译包含变量引用的表达式时,采用”两步走”评估模式:
- LEN Pass:遍历操作码序列,累加每个片段的字符长度,据此分配精确大小的缓冲区
- VALUE Pass:用相同的操作码序列,向已分配的缓冲区写入实际内容
该设计的核心假设是:每个操作码在两步中产生的长度完全一致。然而,当表达式中同时包含正则捕获组(如$1)和正则map变量时,问题就出现了。
捕获状态污染机制
当location块使用正则匹配时,匹配结果存储在请求对象的r->captures中。这些字段是共享的可变状态——任何后续的正则匹配都会直接覆盖它们,不会保存和恢复原有上下文。
当map指令使用正则模式时,评估map变量会触发ngx_http_regex_exec(),将结果直接写入请求的捕获状态,覆盖掉原始location匹配的捕获数据。这导致LEN和VALUE两个阶段对$1的大小认知不一致:
- 堆溢出:当clobbered capture大于原始值时,VALUE写入的数据超过缓冲区尺寸
- 信息泄露:当clobbered capture小于原始值时,缓冲区 oversized,响应中泄露未初始化的堆内存(包含libc和堆指针,足以单次GET请求绕过ASLR)
攻击面与可靠性
据Cyberstan报告,该漏洞跨越至少13个独立调用点,分布在9个源文件中,同时影响HTTP和stream模块。攻击者仅需发送约1个泄露请求、40个spray连接和1个溢出触发请求,即可在Ubuntu 24.04(全ASLR启用)上实现10/10可靠性的RCE。
Stan Shaw表示将在补丁发布21天后(约8月5日)公开完整POC。此前CVE-2026-42945(nginx Rift,一个更弱的同类漏洞,需关闭ASLR才能可靠利用)在POC公开后不久即遭在野利用。
影响评估
nginx是全球使用量最大的Web服务器和反向代理软件之一,支撑了互联网上相当大比例的网站流量。该漏洞的影响包括:
- 无需认证:任何可访问nginx服务的远程攻击者均可利用
- 配置依赖:仅当配置中同时存在”正则捕获源+正则map变量”时才可触发
- 高可靠性:信息泄露原语可在单次GET请求中绕过ASLR
- 广泛影响:13个调用点跨越HTTP和stream模块,大量常用指令受影响
修复建议
立即升级
- stable分支:升级至nginx 1.30.4或更高版本
- mainline分支:升级至nginx 1.31.3或更高版本
- NGINX Plus:升级至R36 P7或37.0.3.1及更高版本
注意:此前为修复CVE-2026-42945、CVE-2026-9256、CVE-2026-42055、CVE-2026-48142而升级的版本不修复此漏洞,必须再次升级。
配置扫描与缓解
由于暴露取决于配置而非仅版本,建议运行Stan Shaw发布的静态配置扫描工具:
# 安装配置扫描器
git clone https://github.com/0xCyberstan/CVE-2026-42533-Config-Scanner
# 扫描生产配置
python3 scanner.py /etc/nginx/nginx.conf --json
在无法立即补丁的情况下,可手动检查配置中是否存在以下模式:
- 任何使用正则模式的map指令
- 在同一location块或请求上下文中,该map变量与较早的正则捕获组(如
$1)同时被引用
临时缓解:将受影响的正则map转换为使用命名捕获组((?<name>...)),因为命名捕获组不受此漏洞影响。