三个月三爆:NGINX表达式引擎的内存安全困局——2026年7月三大高危漏洞深度解析

2026年7月24日 · 行业动态

2026年7月15日,F5(NGINX母公司)发布三份安全公告(K000162097K000162098K000162100),披露NGINX Plus和NGINX Open Source中存在三个高危内存安全漏洞:

漏洞编号 CVSS v3.1 CVSS v4.0 漏洞类型 影响模块 远程利用
CVE-2026-42533 8.1 (High) 9.2 (Critical) 堆缓冲区溢出 (CWE-122) ngx_http_map_module
CVE-2026-60005 8.2 (High) 8.8 (High) 未初始化内存泄露 (CWE-908) ngx_http_slice_module
CVE-2026-56434 6.5 (Medium) 8.3 (High) Use-After-Free (CWE-416) ngx_http_ssi_module 条件

注: CVSS v4.0评分体系相比v3.1更关注攻击复杂度和实际暴露面,三个漏洞在v4.0下评分均有显著提升,尤其是CVE-2026-56434从Medium跃升至High。

7月18日,NGINX发布修复版本:

然而,修复之路并非坦途。7月20日,Ubuntu发布USN-8563-2公告,宣布回退CVE-2026-42533的修复——原因是补丁引入了ABI变更,可能导致第三方模块不兼容,需进一步调查(据Ubuntu USN-8563-2)。这意味着大量通过Ubuntu官方源部署NGINX的用户,即使执行了apt upgrade,CVE-2026-42533仍处于暴露状态。

CVE-2026-42533:map指令正则缓冲区溢出——15年潜伏的RCE

漏洞本质

这是本次披露中危害最大的漏洞,由安全研究员Stan Shaw(@cyberstan)等人独立发现并报告给F5 SIRT,初始报告时间为2026年5月17日。该漏洞自2011年3月map指令引入正则表达式支持以来便已存在,影响NGINX 0.9.6至1.31.2的全部版本,跨度长达约15年。

根因分析:双遍脚本引擎的信任危机

NGINX的表达式求值采用双遍脚本引擎(two-pass script engine)架构:

  1. 第一遍(LEN轮): 测量输出结果所需的字节数,分配对应大小的堆缓冲区
  2. 第二遍(VALUE轮): 将实际数据写入缓冲区

两遍评估都读取同一个共享可变数组——r->captures(存储在ngx_http_request_t结构体中)。问题在于:当带有正则表达式的map指令在两遍之间执行时,它会静默覆盖该共享的捕获状态,导致LEN轮和VALUE轮对缓冲区大小的判断不一致。

具体触发路径如下:

# 典型受影响的配置模式
map $request_uri $mapped {
    ~^/api/(?P<version>v[0-9]+)/(?<path>.*)$  "${version}_${1}_result";
}

server {
    location ~ /api/(.*) {
        # $1(来自location正则的编号捕获)在$mapped之前被引用
        proxy_set_header X-Api-Info "$1_${mapped}";
    }
}

在此配置中,执行流程为:

  1. LEN轮测量时,$1引用的是location块的捕获(如"users",长度5)
  2. map的正则执行,覆盖了r->captures,将$1指向新的捕获数据
  3. VALUE轮写入时,$1的实际数据可能已变为攻击者控制的超长字符串
  4. 缓冲区按LEN轮的5字节分配,但VALUE轮写入了攻击者控制的任意长度数据——堆溢出发生

两种攻击原语

这一不一致性产生了两种可组合利用的攻击原语:

原语一:堆缓冲区溢出(Heap Buffer Overflow)

当被覆盖的捕获组大于原始捕获组时,VALUE轮写入的数据超过缓冲区大小,用攻击者完全可控的内容破坏相邻堆内存。溢出内容的长度和数据均直接来自HTTP请求(URI、Header、Body),攻击者可精确控制。

原语二:信息泄露(Information Leak)

当被覆盖的捕获组小于原始捕获组时,缓冲区被分配过大,响应中会泄露未初始化的堆字节——包括libc基址和堆指针,足以在单个未认证GET请求中绕过ASLR。

完整RCE攻击链

两种原语可链式组合实现可靠的Pre-Auth RCE:

单个泄露请求(获取堆/libc地址,绕过ASLR)
    ↓
约40个喷射连接(堆布局操纵 / Heap Feng Shui)
    ↓
单个触发溢出的请求(精确覆盖函数指针,劫持执行流)

Stan Shaw报告称,在Ubuntu 24.04默认配置(ASLR开启,glibc 2.39)下,该攻击链实现了10/10成功率的Pre-Auth RCE。

关键分歧: F5的安全公告将RCE描述为"ASLR禁用或可绕过时"的条件性风险,CVSS v4.0攻击复杂性评分为"高"。但Shaw指出,该漏洞本身提供了ASLR绕过能力,实际RCE风险远高于公告描述。"阅读F5安全公告的人可能会合理地认为,在默认系统上该漏洞仅导致拒绝服务。但事实并非如此。"——Stan Shaw,接受The Hacker News采访时说。

影响范围

该漏洞并非影响所有NGINX服务器,是否暴露取决于配置而非仅版本。影响面覆盖9个源文件中的至少13个独立调用点,同时影响HTTP和Stream模块。常见受影响指令包括:

任何将正则捕获源(locationserver_namerewriteif块)与后续在同一请求上下文中评估的基于正则的map变量相结合的配置,都有可能被利用。

此外,F5确认NGINX Ingress Controller、Gateway Fabric、App Protect WAF、Instance Manager等下游产品也受影响,但截至公告发布时尚未列出这些产品的修复版本。

临时缓解

F5建议将受影响的正则map中的未命名捕获($1$2)改为命名捕获($name。Shaw指出,这能堵住大部分攻击路径,但仍留下一条较窄的路径:如果map定义了与location正则相同的命名组,则可通过第二条代码路径触发溢出。

"升级至1.30.4 / 1.31.3是唯一的完整修复方案。"——Stan Shaw

Shaw已发布静态配置扫描器(0xCyberstan/CVE-2026-42533-Config-Scanner),可在不进行任何利用的情况下识别有风险的指令顺序。完整PoC将在补丁发布21天后(约2026年8月5-6日)公布。

CVE-2026-60005:slice模块未初始化内存泄露

模块背景

ngx_http_slice_module提供大文件分片(byte-range)缓存功能,将大文件响应切分为固定大小的切片独立缓存,常见于CDN和视频分发场景。该模块默认不编译,需显式添加--with-http_slice_module构建参数,限制了默认暴露面。

影响版本:NGINX 1.15.8至1.31.2(需模块已编译且配置启用)。

触发条件

漏洞在两种场景下触发:

场景A:slice指令与未命名正则捕获组合

slice模块处理切片请求时,若同一配置上下文中存在使用未命名正则捕获的变量处理逻辑,缓存键的构造过程中会引用未初始化的内存。

场景B:后台缓存更新

proxy_cache_background_update on模式下,后台子请求更新缓存时,slice模块的缓存键构造逻辑访问了未正确初始化的缓冲区。

信息泄露影响

泄露的内存内容可能包括:

检测方法

# 检查NGINX是否编译了slice模块
nginx -V 2>&1 | grep "http_slice_module"

# 在配置中查找slice指令
grep -rn "slice\s" /etc/nginx/ | grep -v "#"

CVE-2026-56434:SSI模块Use-After-Free

模块背景

Server-Side Includes(SSI)允许在HTML页面中嵌入服务器端指令(如<!--#include virtual="/header.html" -->),由ngx_http_ssi_module在响应发送前解析执行。该漏洞由싸이버원(CYBERONE)的安全研究员p4p3r(@P4P3R-HAK)发现并报告。

影响版本:NGINX 0.8.11至1.31.2,跨度极长。

触发条件

该漏洞需要三个配置条件同时满足

  1. ssi on — SSI功能启用
  2. proxy_pass — 使用反向代理
  3. proxy_buffering off — 上游响应缓冲关闭
# 危险配置组合
location / {
    ssi on;
    proxy_pass http://backend;
    proxy_buffering off;  # 关键:关闭缓冲
}

根因分析

proxy_buffering off显著改变了NGINX的内存管理策略:

模式 内存行为 生命周期
proxy_buffering on(默认) 接收完整上游响应到缓冲区,断开上游连接后再进行SSI处理 清晰,缓冲区所有权明确
proxy_buffering off 流式传输,边接收边发送,SSI模块需实时解析数据流中的指令 复杂,存在边界条件

在流式传输模式下,当上游返回特制的SSI指令序列时,ngx_event_pipe可能提前释放某个缓冲区,而SSI模块仍持有对该缓冲区的引用——Use-After-Free发生

攻击前提

该漏洞的利用门槛较高,攻击者需要:

无有效临时缓解

该漏洞位于SSI处理的核心路径,任何配置层面的调整都会破坏业务功能。唯一有效修复方式是升级到已修补版本。

两个月三爆:NGINX表达式引擎的系统性弱点

这三个漏洞并非孤立事件。回溯2026年5-7月的时间线,一幅令人担忧的图景浮现出来:

时间线

时间 事件
2026年5月12日 CVE-2026-42945("NGINX Rift")披露,CVSS 9.2,rewrite模块堆溢出,影响0.6.27至1.30.0
2026年5月下旬 CVE-2026-9256披露,rewrite模块中重叠PCRE捕获导致堆溢出
2026年5月17日 Stan Shaw向F5 SIRT提交CVE-2026-42533初始报告
2026年7月15日 F5发布安全公告,修复CVE-2026-42533、CVE-2026-60005、CVE-2026-56434
2026年7月18日 NGINX 1.30.4 / 1.31.3发布
2026年7月20日 Ubuntu回退CVE-2026-42533修复(ABI兼容问题)

共同弱点:信任自身测量的双遍设计

三个漏洞属于同一类缺陷:NGINX的双遍脚本引擎在一遍中测量缓冲区大小,在下一遍中写入,而每次写入都超出了测量的长度。

漏洞 触发因素 根因
CVE-2026-42945 (Rift) 过期的is_args标志 LEN轮加上了args长度,VALUE轮却没有拷贝args
CVE-2026-9256 重叠的PCRE捕获 嵌套捕获引用导致长度计算偏差
CVE-2026-42533 捕获状态被map正则覆盖 LEN轮和VALUE轮之间r->captures被重写

共同的架构弱点是:双遍设计信任自身测量,假设两次评估之间状态不变。 这是一个典型的Time-of-Check-to-Time-of-Use(TOCTOU)问题,只不过发生在同一个进程内的两次连续遍历之间。

值得注意的是,这种问题行为最早在2014年就被nginx trac工单标记,开发者Maxim Dounin承认这是一个缺陷,但从未作为安全关键问题完全修复。十余年后,它演变为三个独立可利用的高危漏洞。

影响评估与修复建议

影响面评估

NGINX作为全球使用最广泛的Web服务器和反向代理之一,承载着互联网约30%-37%的公开网站流量。

漏洞 直接暴露条件 估计影响范围
CVE-2026-42533 版本0.9.6-1.31.2 + 特定map配置 最广:正则map在反向代理配置中极为常见
CVE-2026-60005 版本1.15.8-1.31.2 + slice模块编译 + 特定配置 较窄:模块默认不编译,主要影响CDN/视频平台
CVE-2026-56434 版本0.8.11-1.31.2 + SSI + proxy_buffering off 较窄:SSI已较少使用,需三个条件同时满足

CVE-2026-42533是影响最大的漏洞:版本跨度最长(15年)、触发配置最常见、潜在后果最严重(Pre-Auth RCE,10/10成功率)、独立于此前Rift等漏洞的修复。

修复建议

优先级一:立即升级

# 确认当前版本
nginx -v

# Debian / Ubuntu(注意:Ubuntu用户需关注USN-8563-2后续更新)
apt update && apt install nginx

# RHEL / CentOS / Rocky / AlmaLinux
dnf update nginx

# 验证升级结果
nginx -v  # 应显示1.30.4(稳定版)或1.31.3(主线版)

⚠️ Ubuntu用户注意: 由于USN-8563-2回退了CVE-2026-42533的修复,通过apt upgrade更新的系统可能仍处于暴露状态。建议关注Ubuntu安全团队的后续公告,或考虑从NGINX官方源安装修复版本。

优先级二:配置审计

# CVE-2026-42533配置扫描
grep -rn "map\s" /etc/nginx/ | grep -E '~.*\$[0-9]'

# 使用Shaw发布的专用扫描器
git clone https://github.com/0xCyberstan/CVE-2026-42533-Config-Scanner.git

# CVE-2026-60005检查
nginx -V 2>&1 | grep "http_slice_module"
grep -rn "slice\s" /etc/nginx/ | grep -v "#"

# CVE-2026-56434检查
for f in $(grep -rln "ssi\s\+on" /etc/nginx/ 2>/dev/null); do
    grep -l "proxy_buffering\s\+off" "$f" 2>/dev/null && echo "[!] VULNERABLE: $f"
done

优先级三:临时缓解

行业反思

C语言的内存安全债务

NGINX用C语言编写,拥有手动内存管理。在2026年,当Rust等内存安全语言已在系统编程领域崭露头角,一个承载着全球三分之一网站流量的核心基础设施组件,仍然因为缓冲区长度计算偏差而被反复攻破——这不仅是NGINX的问题,更是整个C生态系统的系统性债务。

"修一个,冒三个"的安全困境

三个漏洞在代码层面的修复是独立的,因为它们触发的路径不同——但根因相同。这暴露了一个深层问题:当底层架构模式存在系统性弱点时,逐个修补表面症状是无止境的。

供应链安全的连锁效应

NGINX不仅是一个独立的Web服务器,还作为核心组件嵌入在无数产品中:Kubernetes Ingress Controller、各类API网关、负载均衡器、CDN平台。一个底层组件的漏洞,通过供应链层层扩散,影响着远超NGINX直接用户群的组织。

Ubuntu回退事件的警示

Ubuntu在补丁发布仅5天后回退CVE-2026-42533修复,原因竟是ABI兼容性问题。这揭示了一个现实:安全补丁的发布不等于安全补丁的落地。不能假设apt upgrade就万事大吉——需要验证补丁是否真正生效。

21天窗口期

Shaw选择在补丁发布21天后公开PoC,这是一个负责任的披露决策。但CVE-2026-42945(NGINX Rift)的前车之鉴表明,漏洞利用代码在公开后数天内就会被武器化。这21天窗口期,是每个NGINX运维人员必须抓住的生死线。


参考来源: - F5安全公告 K000162097(CVE-2026-42533) - F5安全公告 K000162098(CVE-2026-56434) - F5安全公告 K000162100(CVE-2026-60005) - CVE官方记录:CVE-2026-42533 - Ubuntu安全公告 USN-8563-2 - FreeBuf:NGINX严重漏洞分析 - 博客园:F5 NGINX三大高危漏洞深度解析 - Stan Shaw配置扫描器

本文信息基于公开安全公告、CVE记录及安全研究人员披露,经多源交叉验证。截至发稿(2026年7月24日),CVE-2026-42533尚未被列入CISA KEV目录,无公开漏洞利用代码。Stan Shaw的完整PoC预计于2026年8月5-6日公开。建议所有NGINX运维人员在此之前完成版本升级和配置审计。

← 返回文章列表