漏洞触发与底层原理
这个漏洞藏身于 ngx_http_rewrite_module脚本引擎中,并非所有 NGINX 实例都直接暴露在风险下,必须同时满足以下特定配置组合才会被激活:
配置中存在 rewrite指令,且其替换字符串包含问号 ?(用于分隔路径和参数)。该 rewrite规则使用了未命名的 PCRE 正则捕获组(如 $1, $2)。此 rewrite指令后,紧跟着另一条 rewrite、if或 set指令。
技术根因在于 NGINX 脚本引擎的“两阶段执行”逻辑失配:
长度计算阶段:引擎使用重置状态的临时子引擎计算所需内存,此时遇到 ?设置的 is_args标志未被继承,不对 +、&等特殊字符做 URI 转义,导致计算出偏小的缓冲区长度。数据拷贝阶段:实际写入时切换回主引擎,is_args标志生效,调用 ngx_escape_uri对特殊字符进行转义(如 +转为 %2B),数据体积膨胀。最终,分配偏小的堆缓冲区被超出预期长度的数据写入,引发可控的堆缓冲区溢出。
影响范围与受波及产品
鉴于 NGINX 在全球网站服务器和反向代理领域近 30% 的占有率,影响面极广。主要涉及:
- NGINX Open Source:0.6.27 至 1.30.0 所有版本(1.0.0 及以上均受影响)。
- NGINX Plus:R32 至 R36 分支的早期版本。
- 衍生商业组件:包括 NGINX Ingress Controller (3.5.0-5.4.1)、NGINX Gateway Fabric (1.3.0-2.5.1)、NGINX App Protect WAF / DoS、F5 WAF for NGINX 等多个基于核心构建的企业级产品。
紧急修复与缓解方案
由于公开的 PoC(概念验证代码)已流出,建议运维团队立即采取以下行动:
1. 优先升级到官方修复版本(推荐)
- 开源版 (Open Source):升级至 1.30.1(Stable) 或 1.31.0(Mainline) 及以上。
- 商业版 (NGINX Plus):升级至 R32 P6、R35 P2、R36 P4 或 37.0.0+ 等对应补丁版本。
- 衍生组件:参照 F5 官方安全公告(K000161019)升级到各产品对应的修复版。
2. 临时配置缓解(若无法立即升级)
检查所有配置文件(如 nginx.conf),找到满足条件的 rewrite规则,将未命名捕获组改为命名捕获组(例如把 ([0-9]+)改为 (?<id>[0-9]+),并对应使用 $id引用)。这种改写可以绕过有缺陷的长度计算逻辑,作为临时止血手段。修改后务必执行 nginx -t测试配置并平滑重载。
对于暴露在公网的 NGINX 服务,尤其是运行老旧版本或使用了复杂 rewrite规则的网关、API 入口,建议即刻排查并安排维护窗口更新,防范潜在的自动化扫描与攻击利用。