【漏洞】CVE-2026-42945:NGINX ngx_http_rewrite_module 堆缓冲区溢出深度分析

一、漏洞概述

2026年5月,F5 Networks与美国国家漏洞数据库(NVD)同步披露了CVE-2026-42945。该漏洞存在于NGINX的ngx_http_rewrite_module模块中,根源是一个存在了将近二十年的代码逻辑错误(2008年引入)。

攻击者通过构造特定的HTTP请求,利用rewrite指令配合未命名PCRE捕获组(如$1、$2)且替换字符串中包含问号(?)的场景,可触发堆缓冲区溢出,严重情况下可实现远程代码执行(RCE)。

二、影响范围

产品 受影响版本 修复版本
NGINX Open Source 0.6.27 – 1.30.0 1.31.0、1.30.1
NGINX Plus R32 – R36 R36 P4、R35 P2、R32 P6

三、漏洞评分与分类

  • CVSS 4.0评分:9.3(Critical)
  • 向量串:CVSS:4.0/AV:N/AC:H/AT:N/PR:N/UI:N/VC:H/VI:H/VA:H/SC:N/SI:N/SA:N
  • weakness枚举:CWE-122(Heap-based Buffer Overflow,堆缓冲区溢出)
  • 利用前提:目标服务器关闭了ASLR,或攻击者能绕过ASLR防护

四、技术根因分析

4.1 NGINX rewrite脚本引擎的双阶段处理

NGINX的ngx_http_rewrite_module在处理rewrite规则时,采用了两个独立的处理阶段:

  1. 长度计算阶段(Length Pass):预先计算替换操作后字符串的所需缓冲区大小。
  2. 数据复制阶段(Copy Pass):根据计算出的长度分配堆内存,执行实际的字符串替换复制。

问题出在is_args标志的传递逻辑上。当rewrite替换字符串中包含问号(?)时,is_args标志会在主引擎上被设置为1。然而,长度计算阶段是在一个重新初始化的子引擎(fresh sub-engine)上执行的,该子引擎的is_args初始值为0。

4.2 溢出如何发生

这个标志位差异导致了两个阶段处理逻辑的分裂:

  • 长度计算阶段:is_args=0,系统认为不需要对URI参数进行转义,直接返回原始捕获组(如$1)的字符长度。
  • 复制阶段:is_args=1,系统调用ngx_escape_uri并使用NGX_ESCAPE_ARGS标志对可转义字符进行URL编码转义。每个可转义字节会被扩展为3个字节(%XX格式)。

结果:复制阶段实际写入的数据量 > 长度计算阶段预分配的缓冲区大小,堆缓冲区溢出就此形成。

4.3 利用条件

漏洞的触发需要rewrite指令配合以下条件:

rewrite 正则表达式 替换字符串(包含?) [标志位];

替换字符串中必须包含问号(?),且使用了未命名PCRE捕获组($1、$2等)的引用。

五、危害与利用路径

5.1 拒绝服务(DoS)

最直接的影响是NGINX worker进程因堆缓冲区溢出而崩溃,触发自动重启。在默认编译配置下,ASLR会随机化内存布局,攻击者难以精确控制溢出数据走向,DoS是最常见的实际危害。

5.2 远程代码执行(RCE)

在特定条件下,攻击者可以实施RCE:

  1. ASLR被禁用或攻击者通过其他手段绕过ASLR;
  2. 利用跨请求堆风水(cross-request heap feng shui)技术,控制堆布局使其可预测;
  3. 通过POST请求体喷射(URI字节不能包含空字节,但POST body不受此限制)来操控内存;
  4. 覆写相邻ngx_pool_t结构体中的cleanup指针
  5. 将该指针指向一个伪造的ngx_pool_cleanup_s结构,在pool销毁时调用system()执行任意命令。

六、修复建议

6.1 升级NGINX版本

这是最根本的修复方式:

  • NGINX Open Source用户:升级至1.31.01.30.1
  • NGINX Plus用户:升级至R36 P4R35 P2R32 P6

6.2 临时缓解措施

如果暂时无法升级,可采取以下措施降低风险:

  1. 检查所有rewrite规则,确认是否存在替换字符串包含"?"且使用了$1/$2等捕获组的配置;
  2. 如非必要,移除或重写相关rewrite规则;
  3. 在边界设备(如防火墙/负载均衡)上限制对内部服务器的HTTP请求来源;
  4. 启用ASLR、堆保护等系统级内存安全机制。

6.3 安全监测

建议在WAF/IDS设备上添加针对以下特征的检测规则:

  • 请求URI中包含与rewrite规则正则匹配的内容;
  • 请求同时携带异常大量的PCRE捕获组引用;
  • 同一IP在短时间内发起大量rewrite规则的请求。

七、总结

CVE-2026-42945是一个典型的因历史代码逻辑缺陷累积而成的严重漏洞,2008年引入的bug在十八年后才被发现和修复。其双阶段处理中is_args标志传递不一致的问题,暴露了NGINX rewrite模块在安全边界处理上的设计疏漏。

漏洞的CVSS评分达到9.3(Critical),理论上支持RCE利用,但实际利用需要攻击者具备精确的堆布局控制能力,门槛不低。尽管如此,考虑到NGINX在全球Web服务器的极高占有率(Apache外最广泛使用的HTTP服务器),此漏洞的影响面不容轻视。

建议所有使用NGINX的用户尽快确认当前版本,如在受影响范围内应立即升级或采取临时缓解措施。


参考来源:

Logo

openEuler 是由开放原子开源基金会孵化的全场景开源操作系统项目,面向数字基础设施四大核心场景(服务器、云计算、边缘计算、嵌入式),全面支持 ARM、x86、RISC-V、loongArch、PowerPC、SW-64 等多样性计算架构

更多推荐