在全球互联网基础设施的底层架构中,NGINX 凭借其极致的异步非阻塞事件驱动模型和极低的内存消耗,长期占据着 Web 服务器、反向代理、负载均衡器以及 API 网关领域的统治地位。NGINX的安全性影响全球数以千万计在线服务。2026年5月13日,一项被正式命名为 “NGINX Rift” 的严重内存破坏漏洞(CVE-2026-42945)的公开披露,在网络安全业界引发了强烈的震动。
该漏洞极其罕见地在 NGINX 的核心源码库中潜伏了大约 18 年之久(据溯源分析,该缺陷最早在 2008 年左右的提交中被引入),波及了从 0.6.27 早期版本一路延伸至 1.30.0 的几乎所有 NGINX Open Source 迭代分支,同时 NGINX Plus 商业版也未能幸免 。作为一个潜藏极深的基于堆的缓冲区溢出漏洞,它存在于被极为高频使用的 URL 重写模块(ngx_http_rewrite_module)中 。在极具普遍性的特定配置模式下,未经身份验证的远程攻击者仅需发送一个精心构造的单一 HTTP 请求,即可稳定触发该溢出漏洞,导致 NGINX 工作进程(Worker Process)崩溃,形成极高效率的拒绝服务(DoS)攻击。更为致命的是,在特定环境中,该漏洞的堆内存破坏特性允许攻击者实现无前置条件的远程代码执行,从而彻底接管服务器实例。
根据 F5 官方安全公告(K000161019)以及美国国家漏洞数据库(NVD)的权威评估,NGINX Rift 漏洞在最新的通用漏洞评分系统(CVSS)4.0 标准下获得了 9.2 分的极危(Critical)评级,在 CVSS 3.1 标准下亦达到了 8.1 分的高危(High)水平 。这一评分的内在逻辑深刻反映了该漏洞的破坏力。

该漏洞的波及范围不仅局限于独立部署的 NGINX 服务,更深刻影响了全球主要 Linux 发行版的官方软件源以及基于 Kubernetes 的云原生网络入口控制器。由于该缺陷代码早在 2008 年便已合入主线,这意味着过去 18 年间发布的大量长期支持(LTS)版本均携带此隐患 。

值得高度警惕的是,众多 Kubernetes 集群仍在使用官方主线停止维护的 kubernetes/ingress-nginx 控制器。由于该控制器的底层镜像硬编码并静态嵌入了NGINX 1.27.1 版本,集群管理员无法通过简单地升级宿主机的 NGINX 安装包来解决此问题,必须更换或重新编译入口控制器镜像。这种容器化带来的底层依赖固化,在遇到此类持续时间极长、潜藏极深的超期漏洞时,暴露出供应链安全响应的迟滞风险。
为了彻底解析 NGINX Rift 漏洞的技术肌理,有必要深入剖析 NGINX 处理 HTTP 流量的内部架构及其精妙的内存管理哲学。NGINX 并不为每一个传入的连接生成新的线程或进程,而是采用单线程的事件循环(Event Loop)配合非阻塞 I/O 来处理成千上万的并发连接。
在这种架构下,配置文件的解析与请求路由成为至关重要的一环。ngx_http_rewrite_module 是 NGINX 体系中最复杂、最强大的核心模块之一。它允许管理员利用 PCRE(Perl-Compatible Regular Expressions)正则表达式在请求处理的极早期阶段(Server Rewrite Phase 和 Rewrite Phase)动态拦截、修改、重写传入的统一资源标识符(URI),甚至改变后续的处理走向 。在处理如 PHP 前端控制器(Front Controller)模式、WordPress 伪静态永久链接(Permalinks),或是作为 API 网关桥接公共路径到内部端点时,该模块的使用几乎是不可避免的 。
在内存分配策略上,NGINX 摒弃了频繁调用操作系统层面 malloc 和 free 的低效做法,转而实现了一套基于内存池(Memory Pool, ngx_pool_t)的高效机制。当一个新的 HTTP 请求接入时,NGINX 会为其创建一个独立的请求内存池。在处理该请求生命周期内的所有小块内存分配(如保存解析后的 HTTP 头、动态生成的 URI 字符串等),都会直接从这个预先申请的大块连续内存页中切割。这种设计极大地降低了内存碎片和分配开销。然而,正是这种将多次分配集中在一个连续内存空间中的设计,使得一旦发生逻辑上的计算谬误导致缓冲区越界写入,溢出的字节会直接覆盖并污染同一内存池中紧邻的其他关键数据结构或状态变量,从而产生链式破坏效果 。如果需要分配的缓冲区异常庞大超出了内存池设定的阈值,NGINX 会退化回直接调用底层库的堆分配函数,此时的溢出行为将直接作用于操作系统的核心堆管理结构上 。
DepthFirst团队在漏洞研究报告中详细揭示了 NGINX Rift 的根本原因。这是一个典型且极其复杂的计算逻辑脱节漏洞,其核心在于 NGINX 的内部脚本引擎(Script Engine)在处理特定的变量重组时,对目标内存长度的“预判(Estimation)”与最终的“执行写入(Execution)”之间,存在基于上下文标志位(Context Flags)的严重不对等。
漏洞并非在 NGINX 的常规运行中随机产生,它宛如一把必须通过特定配置齿轮才能咬合转动的复杂暗锁。研究表明,必须同时满足以下三个配置维度的条件,漏洞代码路径才会被激活 :
存在未命名的 PCRE 正则捕获:在 rewrite 指令的正则表达式中,使用了未命名的捕获组,随后在配置逻辑中通过系统自动分配的数字变量(如 $1, $2)进行引用。
替换字符串引入查询参数机制:在目标替换字符串(Replacement String)中嵌入了问号(?)。在 NGINX 的路由语义中,这标志着 URI 路径与查询参数(Query String)的分界,NGINX 会据此改变对后续字符的转义处理逻辑。
同一作用域下的指令链式调用:在这个存在隐患的 rewrite 指令之后,在同一个配置块(Scope)内,必须紧跟另一个触发脚本引擎重新评估的指令,通常是另一个 rewrite,或者是 if 逻辑判断,亦或是 set 变量赋值指令 。
一个能够精准命中上述所有脆弱条件的真实生产环境配置切片如下所示:
# 典型的 API 网关或应用重写逻辑
location /api/v1/ {
# 步骤一与二:正则表达式使用 (.*) 产生未命名捕获 $1,替换字符串包含? 号
rewrite ^/api/v1/(.*)$ /internal_router.php?route=$1;
# 步骤三:紧跟一个 set 指令,触发双重遍历引擎的上下文混乱
set $backend_cluster "legacy_nodes";
}当攻击者向具备上述配置的 NGINX 节点发送包含特殊荷载的 HTTP 请求时,NGINX 将进入其内置的脚本求值流程。位于 src/http/ngx_http_script.c 源码文件中的底层机制被唤醒。由于指令链条的复杂性,NGINX 需要对重写目标进行两次遍历操作 :
第一遍遍历:长度分配的短视计算 引擎必须首先计算出需要多大的目标缓冲区来容纳重写后的 URI。此时,系统调用了 ngx_http_script_complex_value_code 函数。至关重要的是,为了进行纯粹的长度评估,NGINX 在这一步实例化并传入了一个被完全清零初始化的“子引擎(Sub-engine)”结构体 。 在这个被清零的子引擎上下文中,一个名为 is_args 的关键标志位被默认为 0。当子引擎进一步调用 ngx_http_script_copy_capture_len_code 去测量正则表达式捕获的内容(即攻击者传入的恶意 $1 变量)时,由于 is_args 为 0,代码路径决定以最原始的原始字节数(Raw Bytes)来衡量其长度,完全忽略了后续可能发生的任何字符转换或转义膨胀 。引擎据此得出了一个严重偏小的缓冲区需求量,并在堆内存中完成了分配。
第二遍遍历:数据写入的转义膨胀 一旦空间分配完毕,执行流程随即切换到第二遍的实际数据拷贝阶段。此时,操作权交还给了保留完整上下文状态的“主引擎(Main engine)”。 在主引擎的上下文中,由于之前的替换字符串中显式包含了 ? 符号,系统正确识别到当前正在处理 URI 的查询参数区域,因此 is_args 标志位被正确地保持为 1。 当程序执行到 ngx_http_script_copy_capture_code 准备将攻击者的数据拷贝入刚刚分配的缓冲区时,悲剧发生了。由于检测到 is_args 为 1,NGINX 强制介入了参数转义流程,调用了底层的 ngx_escape_uri 函数,并以 NGX_ESCAPE_ARGS 模式运行 。
在 NGX_ESCAPE_ARGS 转义模式下,根据相关 RFC 标准,特定的字符必须被编码以保证安全传输。例如:
空格会被转化为 + 或 %20。
字符 +、% 和 & 等会被展开为三字节的十六进制表示形式(如 % 会被重新转义为 %25)。
致命的算术冲突与内存覆写:
假设攻击者发送的请求 URI 中包含了 1000 个连续的 % 字符。
计算阶段:子引擎认为这是一个长度为 1000 字节的数据块,向内存池申请了 1000 字节的目标缓冲区。
写入阶段:主引擎在拷贝过程中,对这 1000 个 % 字符执行 NGX_ESCAPE_ARGS 转义,每一个 % 都被转换成了长达 3 个字节的 %25 字符串。最终,主引擎试图将高达 3000 字节的数据强行塞入仅仅分配了 1000 字节的内存块中 。
这导致了多达 2000 字节的高强度越界写入。由于越界写入的字节流实质上是对攻击者原始输入的转义版本,这意味着内存覆写的内容并不是完全的乱码,而是由攻击者高度可控的数据载荷构成的,这种“可控的内存破坏(Controllable Corruption)”正是将其转化为严重安全漏洞的核心原因 。
了解了 NGINX Rift 漏洞的根本成因后,有必要进一步剖析攻击者是如何在实战环境中运用这一缺陷的。根据底层操作系统环境的防御纵深配置不同,该漏洞能够造成的破坏程度呈现出巨大的两极分化态势。
对于绝大多数开启了现代内存保护机制的系统而言,漏洞最直观和最可靠的表现形式是拒绝服务。由于 NGINX 采用 Master-Worker 多进程架构,工作进程(Worker)负责处理具体的网络请求连接。
当攻击者发送包含大量恶意字符膨胀载荷的请求时,堆缓冲区溢出瞬间发生。溢出的数据无情地践踏了紧邻其后的内存结构。如果该内存处于 NGINX 自定义的 ngx_pool_t 结构内,它会破坏下一个即将被使用的内存块的元数据头部;如果触发了针对大块内存的 malloc 退化,它将破坏底层 glibc(如 ptmalloc)管理堆块(Chunk)所必需的头部信息(例如覆盖了关键的 size 字段或是双向链表的 fd/bk 指针)。
当 NGINX 进程继续运行,试图释放该内存块或在同一池中进行下一次分配时,底层的内存完整性校验机制将被触发。系统侦测到堆数据损坏,会立即抛出 SIGSEGV(段错误)或 SIGABRT 异常中断,直接杀死当前正在处理该请求的 Worker 进程 。虽然 NGINX 的 Master 进程拥有强大的韧性,它会在监控到 Worker 退出(例如在日志中记录类似 worker process <PID> exited on signal 11 的信息)后迅速拉起一个新的替补 Worker,但为攻击者提供了一种极其廉价且高效的攻击途径 。
攻击者可以构建多线程发包工具,以每秒数百次的频率持续发送触发载荷。这种高频的精确打击将导致目标服务器上的所有 NGINX Worker 进程陷入永无止境的“崩溃-重启”死亡循环(Crash Loop)中 。合法的用户请求由于分配不到存活的 Worker 进程,或者连接在处理半途中因进程意外死亡而遭到系统强行重置(Connection reset by peer),从而导致目标 Web 业务或 API 服务呈现全面瘫痪的状态 。在 Alma Linux 团队的独立复现测试中,他们确认在 Alma Linux 8、9、10 及后续衍生版本上,针对目标 Worker 进程制造此类 DoS 攻击路径是微不足道的任务 。
多份深度研究报告明确指出,CVE-2026-42945 确实存在被转化为无身份验证 RCE 的完整潜能,然而这其中存在一个至关重要的先决门槛—目标主机的地址空间布局随机化(ASLR)状态 。
在默认开启 ASLR 的环境下,由于堆布局的不可预测性,且当前尚未发现能与此溢出相配合的稳定信息泄露(Info-leak)漏洞,攻击者通过盲目构造溢出载荷去精准覆盖如 NGINX 核心结构体中的 handler 回调函数指针,并将其重定向至有意义的执行链(ROP Chain)的成功率微乎其微。强行尝试的结果绝大多数情况下依然是引发不可恢复的段错误崩溃 。
然而,如果目标系统由于特定的历史遗留原因、兼容性约束、特殊的调试配置,或是某些极度精简的物联网(IoT)固件/老旧嵌入式环境中被人为或被迫禁用了 ASLR(例如配置了 sysctl kernel.randomize_va_space=0)。
在此类未受 ASLR 保护的脆弱环境中,内存的分配模式变得相对静态和确定。Depth First 平台发布的概念验证(PoC)代码成功展示了,在关闭 ASLR 后,攻击者可以通过高度复杂的堆风水(Heap Grooming)技巧,利用合法的请求预先占据特定的堆孔洞,使得目标被覆写的关键回调结构精确落在漏洞溢出覆盖的物理范围之内 。通过精确控制在 $1 捕获变量中输入的字符构成和序列,最终实现对 NGINX 执行控制流的精准劫持,顺利完成无需任何身份验证的底层 Shell 获取,实现了真正意义上的灾难性突破 。
除了 NGINX Rift,F5 和开源社区在同一批次的补丁更新中,还集中修补了其他多个同样涉及内存破坏和逻辑错乱的安全漏洞,形成了一个规模庞大的“漏洞补丁包”:

根除 CVE-2026-42945 的唯一终极方案,是用修复了内部引擎转义差异缺陷的安全版本彻底替换脆弱代码。安全补丁通过引入更为一致的状态管理逻辑,确保在长度预估和实际拷贝阶段,对于 URI 逃逸字符的判定标准保持绝对统一。
对于原生的 NGINX Open Source 用户:必须将系统平滑升级至 1.30.1(稳定分支)或 1.31.0(主线分支)以上版本 。
对于使用 NGINX Plus 订阅的商业用户:根据生产环境当前固定的发行列车(Release Train),快速部署对应版本的官方安全修正包,包括 R32 P6、R35 P2 或 R36 P4 。
Linux 发行版软件包管理的跟进:对于通过 apt 或 yum 等包管理器直接从发行版软件库安装 NGINX 的服务器。各主流操作系统社区已迅速响应。例如,Ubuntu 已为 26.04 LTS (resolute) 推送了 1.28.3-2ubuntu1.1,为 24.04 LTS (noble) 提供了 1.24.0-2ubuntu7.8 的安全迭代 ;而 Alma Linux 生态圈内,版本 8、9、10 的用户需立刻更新到诸如 nginx-1.14.1-9.el8.10.alma.1 等包含了向上移植(Backport)代码的新编译包 。在利用包管理器升级后,必须手动执行重启命令(如 systemctl restart nginx),单纯的重载(reload)配置无法彻底替换内存中正在运行的脆弱二进制核心程序 。
由于 Kubernetes 官方维护的 ingress-nginx 核心控制器项目当前处于已归档停止推进的状态,其最终正式版控制器镜像内部锁死并静态编译的仍然是易受攻击的 NGINX 1.27.1 版本 。这是极为危险的供应链安全陷阱:即使系统管理员在承载集群计算节点的宿主机操作系统上更新了 NGINX 的 RPM 或 DEB 包,也对运行在容器内部的控制器进程毫无帮助。
应急审计与规避措施:
集群管理员必须进入特定的 Pod 内部执行诊断命令,直接质询编译二进制文件的版本状态:kubectl exec -n ingress-nginx <controller-pod> -- /nginx-ingress-controller --version 。
战略性架构剥离:借此安全事件为契机,加速淘汰陈旧的 Ingress 架构,全面向更为现代、安全解耦的 Kubernetes Gateway API 实施规范演进 。
短效替代品(Fork 方案):在架构平移完成前,对于无法忍受业务断档的企业,建议将其入口控制器的基础镜像临时替换为由社区积极维护、并且及时合并了上游最新安全补丁(1.30.1+ 核心)的分支项目源(例如 Forkline 项目发布的分支镜像)。
核心思路:瓦解触发条件链。因为该溢出极其依赖特定语法符号的堆叠,破坏其中任何一环,都能让漏洞的“预分配与实际执行错位”现象不再发生。
全面使用命名捕获替代未命名系统捕获: 这是最为推荐且影响最小的手段。安全团队需要利用自动化脚本工具,对全网范围内所有的 nginx.conf 及其被包含子配置文件进行地毯式扫描,搜索类似 (.*) 这种依赖 $1, $2 被动赋值的原始正则表达式。 随后,将其全部重构为带有显式名称标识的捕获组,例如使用 (?<my_custom_name>.*) 语法,并在后续的重写路径中显式调用 $my_custom_name。这一语法层面的细微变化,足以改变内部脚本引擎在参数解析时的作用域边界和状态传递链条,完美规避底层缺陷 。
脆弱的配置模式(切勿再使用):
rewrite ^/api/(.*)$ /v2/api.php?query=$1;
set $endpoint "api_v2";安全配置模式:
# 将被动的 $1 升级为具有隔离性的命名捕获 <apipath>
rewrite ^/api/(?<apipath>.*)$ /v2/api.php?query=$apipath;
set $endpoint "api_v2";打破指令链枷锁:如果业务重写规则的复杂度允许,可以直接将替换字符串中的问号(?)剔除,或者拆解紧接在其后的 set 或 if 指令,彻底阻断触发执行第二次评估渲染环境所需的“连击(Combo)”条件 。
如果组织环境内部依然存留着使用脆弱配置且未及更新的 NGINX 实例,那么在被动防御系统上建立高敏态势感知规则是抵御攻击的最后一道壁垒。
建立高敏感的崩溃信标(Crash Beacons):基于此漏洞极其稳定地引发进程终止的特性,防守方应在 SIEM(安全信息和事件管理系统)、Logstash 或集中式的可观测性平台上部署特殊的检测启发式规则。一旦通过模式匹配识别到 NGINX 错误日志中开始大量、规律性地浮现诸如 worker process exited on signal 11 或类似指向 SIGSEGV 断流的关键事件报错,且同一时间维度的 HTTP 访问日志中伴随出现源自特定 IP 范围、含有大量超常编码字符(如冗长的未编码 % 或 + 串列)的异常请求,应当立即触发红色预警响应协议,拉黑关联攻击源,防止针对目标基础设施制造持久化的拒绝服务灾难 。
系统底层防御基线红线审查:安全运维工程师必须针对所有承载着对公网暴露(Internet-facing)NGINX 实例的核心服务器及虚机容器,执行底层的基线回溯审查。重点审查操作系统的地址空间布局随机化(ASLR)核心状态(通过确认 sysctl kernel.randomize_va_space 返回值是否为默认的安全值 2)。如若发现任何因特殊的兼容性诉求、早期的环境隔离配置或是由于承载于不规范硬件上而人为导致 ASLR 完全禁用或被削弱的主机节点,必须将其安全修复优先级上提至最高紧急(P0)级别,因为只有在这类脆弱且无防护伞的环境下,NGINX Rift 漏洞才有可能被实打实地转化为接管系统的终极 RCE 杀伤链 。
本课程最终解释权归蚁景网安学院
本页面信息仅供参考,请扫码咨询客服了解本课程最新内容和活动