【紧急安全通告】NGINX 曝出 18 年老漏洞 CVE-2026-42945:堆溢出可致远程代码执行,附完整修复方案

作者 lucy · 2026-05-19

⚠️ 声明:本文相关内容仅供参考,实际效果因场景不同可能差异很大,请结合自身情况判断,谨慎参考。

⚠️ 重要安全通告:2026年5月13日,F5 Networks 官方发布了多个 NGINX 安全漏洞公告,其中包含一个存在了18年的严重远程代码执行(RCE)漏洞。本文将详细分析这四个漏洞的技术细节、影响范围及修复方案。

🚨 一、漏洞概览

本次披露的四个漏洞均由安全公司 depthfirst 的自动化分析系统自主发现,于2026年4月18日在对 NGINX 源码进行扫描时一次性捕获。以下是四个漏洞的总览:

CVE 编号 严重等级 CVSS 漏洞类型 受影响模块
CVE-2026-42945 🔴 严重 9.2 堆缓冲区溢出 ngx_http_rewrite_module
CVE-2026-42946 🟠 高危 8.3 过度内存分配 ngx_http_scgi_module / ngx_http_uwsgi_module
CVE-2026-40701 🟡 中危 6.3 释放后使用(UAF) ngx_http_ssl_module
CVE-2026-42934 🟡 中危 6.3 越界读取 ngx_http_charset_module

🔍 二、核心漏洞详解:CVE-2026-42945(Critical · CVSS 9.2)

漏洞本质

这是一个潜伏了 18 年的堆缓冲区溢出漏洞,最早可追溯到 2008 年的 NGINX 0.6.27 版本。漏洞位于 NGINX 的脚本引擎 src/http/ngx_http_script.c 中。

触发条件

当 NGINX 配置中存在以下模式时,漏洞可被触发:

  • 使用 rewrite 指令,且替换字符串中包含问号(?)
  • 在同一个作用域内,后面跟着 rewriteifset 指令
  • 使用了未命名的 PCRE 捕获组(如 $1$2

存在风险的配置示例:

location ~ ^/api/(.*)$ {
    rewrite ^/api/(.*)$ /internal?migrated=true;
    set $original_endpoint $1;
}

根因分析

NGINX 脚本引擎采用两阶段处理:第一阶段计算所需缓冲区长度,第二阶段将实际数据写入。问题出在:

  1. rewrite 替换字符串包含 ? 时,ngx_http_script_start_args_code 函数会设置 e->is_args = 1,且永远不会重置
  2. 长度计算阶段使用全新的子引擎(le),is_args 为 0 → 按原始长度计算
  3. 拷贝阶段使用主引擎,is_args 为 1 → 对 URI 字符进行转义,每个可转义字符膨胀为 3 字节
  4. 写入量远超分配的缓冲区大小 → 堆缓冲区溢出

利用方式

攻击者可通过精心构造的 HTTP 请求实现未认证远程代码执行(RCE)

  • 利用跨请求堆布局技术(Heap Feng Shui)控制内存布局
  • 通过 POST 请求体喷射伪造的 ngx_pool_cleanup_s 结构
  • 覆盖 ngx_pool_tcleanup 指针,使其指向攻击者控制的 system() 函数调用
  • NGINX 的多进程架构使得堆布局在 worker 进程间完全确定性,可反复尝试

depthfirst 已在 GitHub 上公开了 PoC 概念验证代码。

🟠 三、CVE-2026-42946(High · CVSS 8.3)

模块:ngx_http_scgi_module / ngx_http_uwsgi_module

漏洞类型:过度内存分配(CWE-789)+ 越界指针偏移(CWE-823)

当配置了 scgi_passuwsgi_pass 时,上游服务器响应中的状态行读取不完整会导致跨缓冲区指针减法错误,产生约 1TB 的键长度,直接导致 worker 进程崩溃。具备中间人(MITM)能力的攻击者可利用此漏洞读取 NGINX 工作进程的内存或使其重启。

🟡 四、CVE-2026-40701(Medium · CVSS 6.3)

模块:ngx_http_ssl_module

漏洞类型:释放后使用(CWE-416)

ssl_verify_client 设置为 onoptional,且 ssl_ocsp 设置为 on 或配置了 leaf 参数的解析器时,如果 TLS 连接在异步 OCSP DNS 解析完成前关闭,上下文内存池会被销毁但解析器请求未被取消。DNS 定时器随后会解引用已释放的指针,可能导致数据有限修改或 worker 进程重启。

🟡 五、CVE-2026-42934(Medium · CVSS 6.3)

模块:ngx_http_charset_module

漏洞类型:越界读取(CWE-125)

当配置了 charsetsource_charsetcharset_map 以及禁用缓冲的 proxy_passoff)时,处理跨代理缓冲区边界的不完整 UTF-8 序列时存在差一错误(off-by-one),导致长度状态损坏,计算出负的源偏移量,读取分配的上游缓冲区之前 2 字节的内存数据。

📦 六、受影响版本

  • NGINX Open Source:0.6.27 – 1.30.0
  • NGINX Plus:R32 – R36
  • NGINX Instance Manager:2.16.0 – 2.21.1
  • F5 WAF for NGINX:5.9.0 – 5.12.1
  • NGINX App Protect WAF:4.9.0 – 4.16.0、5.1.0 – 5.8.0
  • NGINX Gateway Fabric:1.3.0 – 1.6.2、2.0.0 – 2.5.1
  • NGINX Ingress Controller:3.5.0 – 3.7.2、4.0.0 – 4.0.1、5.0.0 – 5.4.1

不受影响:F5 Distributed Cloud、F5 Silverline、NGINX One Console、BIG-IP、BIG-IQ、F5OS、Traffix SDC、F5 AI Gateway。

🛡️ 七、修复方案

⚠️ 修复前必做:备份!备份!备份!

在执行任何修复操作之前,请务必完成以下备份步骤:

# 1. 备份 NGINX 配置文件
cp -a /etc/nginx /etc/nginx.bak.$(date +%Y%m%d)

# 2. 备份当前 NGINX 二进制文件
cp $(which nginx) $(which nginx).bak.$(date +%Y%m%d)

# 3. 如果是容器化部署,备份镜像
docker commit $(docker ps -q -f "ancestor=nginx") nginx-backup:$(date +%Y%m%d)

# 4. 记录当前版本
nginx -V 2>&1 | tee ~/nginx-version-before-fix.txt

方案一:升级到修复版本(推荐)

产品 受影响版本 修复版本
NGINX Open Source 0.6.27 – 1.30.0 1.31.01.30.1
NGINX Plus R32 – R36 R36 P4R35 P2R32 P6

升级步骤(以 Ubuntu/Debian 为例):

# 更新软件源并升级
sudo apt update
sudo apt install -y nginx

# 验证版本
nginx -v

# 重启 NGINX 使新二进制生效
sudo systemctl restart nginx

# 验证服务正常
curl -I http://localhost

升级步骤(以 CentOS/RHEL 为例):

sudo yum update nginx
sudo systemctl restart nginx
nginx -v

容器化环境:

# 拉取最新镜像
docker pull nginx:latest

# 重新部署(Kubernetes)
kubectl rollout restart deployment/nginx-deployment

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

针对 CVE-2026-42945,将所有未命名捕获组替换为命名捕获组

❌ 存在风险的写法:

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 平滑重载。

快速检查脚本

使用以下命令快速排查你的 NGINX 配置是否存在风险模式:

# 检查是否存在 rewrite + 未命名捕获组 + 问号的组合
grep -rn 'rewrite.*\$[0-9].*?' /etc/nginx/ 2>/dev/null

# 检查 NGINX 版本
nginx -v 2>&1 | grep -E '1\.(2[0-9]|30)\.'

💡 八、事件观察与思考

1. 一个存在 18 年的漏洞意味着什么?

CVE-2026-42945 自 2008 年引入,至今整整 18 年。NGINX 是全球使用最广泛的 Web 服务器之一,占据全球约三分之一的网站份额。这意味着这个漏洞在漫长的岁月里默默潜伏在互联网基础设施的核心位置,几乎每一个使用 rewrite 配置的 NGINX 实例都可能受到影响。

2. AI 自动化漏洞发现的里程碑

值得注意的是,这四个漏洞全部由 depthfirst 的自动化安全分析系统自主发现——仅仅通过对 NGINX 源码的一次点击式导入扫描,6 小时内便识别出 5 个安全问题(其中 4 个被 NGINX 团队确认)。这标志着 AI 驱动的漏洞挖掘已经进入实用阶段,对开源基础设施的安全审计将产生深远影响。

3. 堆利用技术的演进

该漏洞的利用链展示了现代堆利用技术的精妙之处:跨请求堆布局控制、POST 请求体喷射、确定性多进程内存布局利用。即使在 ASLR 开启的环境下,攻击者仍可通过逐字节覆盖和反复尝试来绕过防护。这对所有使用 NGINX 作为入口网关的组织敲响了警钟。

4. 配置即攻击面

这个漏洞的触发完全依赖于配置模式——rewrite + set + 未命名捕获组 + 问号。这是许多 Web 应用中极为常见的配置模式。安全不仅仅是代码层面的事,配置审计同样重要。

📋 九、信息来源

以上信息截至 2026 年 5 月 19 日,后续可能有更新,请关注官方公告。

发表评论

苏ICP备18039580号-2