CVE-2026-42945,被称为“NGINX Rift”,一个在 Nginx 代码库中隐藏了整整18年的堆缓冲区溢出漏洞。影响范围覆盖 Nginx 0.6.27 到 1.30.0 之间的几乎所有版本——全球约37%的Web服务器暴露在风险中。攻击者仅需一条恶意 HTTP 请求,就能让 Nginx 工作进程崩溃,在特定条件下甚至可远程执行代码。本文不绕弯子,直接告诉你漏洞原理、排查方法、升级步骤以及临时缓解措施。

一、漏洞深潜:一次“算错账”的内存操作

1. 根源:脏的 is_args 标志位

漏洞位于 ngx_http_rewrite_module。当 Nginx 脚本引擎执行“两遍处理”(先算长度,再拷贝数据)时,如果遇到连续的 rewrite/if/set 指令 + 未命名正则捕获($1, $2) + 替换串带问号(?),内部 is_args 标志位没有被正确清理。第一遍计算长度时错误地将问号后参数长度计入缓冲区,但实际拷贝时又缺少这些数据,最终导致堆缓冲区溢出。攻击者通过在 URI 填充大量可转义字符(例如加号 “+” 变成 “%2B”,1字节变3字节),精准控制溢出内容。

2. “裂谷链”:不止一个CVE

研究人员共披露四个关联漏洞,统称“Rift链”。组合攻击可放大危害。

CVE-2026-42945 — 严重(9.2) — ngx_http_rewrite_module — 堆溢出 → 可导致RCE

CVE-2026-42946 — 高(8.3) — ngx_http_scgi_module / uwsgi_module — 过量内存分配(~1TB) DoS

CVE-2026-40701 — 中(6.3) — ngx_http_ssl_module — Use-After-Free 内存破坏

CVE-2026-42934 — 中(6.3) — ngx_http_charset_module — 越界读取信息泄露

二、影响范围与攻击后果:你的服务器在“射程”内吗?

受影响版本(几乎所有主流发行版)

Nginx Open Source:0.6.27 至 1.30.0(含1.0.x, 1.2.x, 1.4.x ... 1.30.x)

Nginx Plus:R32 ~ R36

衍生组件:NGINX Ingress Controller 特定版本,Nginx Gateway Fabric 1.3-2.5

不受影响版本:Nginx ≥ 1.30.1 或 ≥ 1.31.0;Nginx Plus ≥ R32 P6 / R36 P4 / R37.0.0。

容易被忽略:Nginx 0.6.27~0.9.7 也在影响范围内,但官方已停止维护,没有任何补丁。如果还在这些超老版本上运行,必须立即升级到现代版本。

触发条件:不是所有Nginx都“中招”

配置中必须存在特定的 rewrite 组合模式。如果没有使用 rewrite 模块,或者所有正则捕获都用命名捕获(例如 (?<id>[0-9]+) 代替 $1),则不受影响。

攻击后果:从崩溃到完全接管

DoS拒绝服务攻击 —— 最易实现,成功率接近100%:一个恶意请求就能让Nginx worker进程崩溃,业务中断。

RCE远程代码执行 —— 需要绕过ASLR,但在内网老旧系统或ASLR关闭的环境中极易实现。VulnCheck已观测到野外利用

信息泄露 —— 配合CVE-2026-42934,攻击者可读取进程内存中的敏感数据(如API密钥、session等)。

三、修复方案:立即行动的四步指南

方案一:升级到安全版本(首选且最彻底)

生产环境推荐:Nginx Open Source 1.30.1

商业用户:Nginx Plus R32 P6 / R36 P4 / R37.0.0+

# 从源码编译升级 (通用Linux)
# 1. 备份
cp -r /etc/nginx /etc/nginx.backup
cp /usr/sbin/nginx /usr/sbin/nginx.backup

# 2. 下载并编译
wget https://nginx.org/download/nginx-1.30.1.tar.gz
tar -xzf nginx-1.30.1.tar.gz
cd nginx-1.30.1
./configure --prefix=/etc/nginx --sbin-path=/usr/sbin/nginx --with-http_ssl_module [原有参数]
make && make install

# 3. 测试并重启
nginx -t && systemctl restart nginx

Debian/Ubuntu 包管理器升级: apt update && apt install --only-upgrade nginx

CentOS/RHEL/AlmaLinux: yum update nginx

方案二:临时缓解(无法立即升级时)

步骤1:定位危险配置模式

grep -RnIE 'rewrite|set|\$[0-9]|if\s*\(' /etc/nginx

然后人工检查组合:rewrite 中含 $1,$2 并且替换字符串带问号,且其后紧跟另一条 rewrite/if/set 指令。

步骤2:将所有未命名捕获组改为命名捕获组

错误写法(危险):

rewrite ^/users/([0-9]+)/profile/(.*)$ /profile.php?id=$1&tab=$2 last;

正确写法(安全):

rewrite ^/users/(?<user_id>[0-9]+)/profile/(?<section>.*)$ /profile.php?id=$user_id&tab=$section last;

修改完成后 nginx -t && nginx -s reload

方案三:高风险环境额外加固

检查并开启ASLR:cat /proc/sys/kernel/randomize_va_space → 必须返回2;若返回0,echo 2 > /proc/sys/kernel/randomize_va_space 并写入 /etc/sysctl.conf

部署WAF规则(如果使用NGINX App Protect WAF,升级至4.16.0+)。

限制可访问Nginx的源IP(临时止血,但不能根本解决)。

四、深度洞见:18年的债,现在必须偿还

2008年,一段错误的 rewrite 处理逻辑被引入 Nginx 核心。此后 18 年间,人工审计、传统SAST都没能发现它。最终,DepthFirst 公司的 AI 代码扫描平台在百万行代码中揪出了这处异常的内存操作。这起事件给行业敲响警钟:

运维层面: 版本管理绝不是可选项。许多生产环境依然跑着 5年甚至10年前的Nginx,风险敞口巨大。PoC公开后48小时内必须完成影响评估和打补丁计划。

架构层面: rewrite 模块极其强大但也极其危险。新项目优先考虑 OpenResty 或 迁移到 Kubernetes Ingress(基于最新 Nginx 版本),减少对复杂 rewrite 逻辑的深度依赖。

安全运营层面: AI驱动的代码审计能力已被验证。团队应将AI静态分析纳入常态化漏洞挖掘流程,弥补人工覆盖局限。

总结检查清单(立即执行)

扫描配置中是否出现危险 rewrite 模式 → 未命名捕获 + 连续rewrite/if/set

检查 Nginx 版本号 nginx -v,是否低于 1.30.1

若不能升级,立刻改为命名捕获组

确认ASLR开启状态(cat /proc/sys/kernel/randomize_va_space)

安排生产变更窗口,升级至Nginx 1.30.1或商业版修复包

五、常见问题FAQ

Q1:完全没使用 rewrite 模块,是否受影响?

如果配置中没有任何 rewrite、set 或 if 指令,则不受 CVE-2026-42945 直接影响。但仍建议升级到最新版,因为其他CVE(如 charset 模块越界读)可能通过其他模块触发。

Q2:升级会不会影响业务配置兼容性?

从 1.30.0 → 1.30.1 属于小版本修复,完全向后兼容,不会影响现有重写规则。但强烈建议升级前完整备份配置,并灰度测试。

Q3:临时修改命名捕获组后,所有 rewrite 都需要改吗?

只有那些同时满足“使用 $1/$2 数字捕获 + 替换字符串含问号 ? + 后接另一 rewrite/if/set”才需要改。最简单的做法是将全部未命名捕获统一改为命名捕获,既安全又避免将来的隐患。