nginx regex map 堆溢出排查:两遍求值下的捕获覆盖、版本范围与缓解
2026 年 7 月,nginx 官方修复了一个 regex map 指令在特定组合下可造成堆缓冲区溢出的漏洞。最严重的版本里不止是 worker 崩溃,配合 ASLR 被绕过后能到代码执行。下面按排查路径记录:怎么触发、哪些配置命中、如何自查、临时缓解和升级建议。
触发面:两遍求值模型下正则捕获被覆盖
根因在 nginx 脚本引擎对「复杂值变量」的求值方式:先跑一遍算长度,再跑一遍填数据。两遍之间,如果某个 regex map 的匹配操作把正则捕获的共享状态($1、$2…)改掉了,第一遍量出的长度就和第二遍实际写入的大小对不上,于是越界写。
要触发,配置上通常要同时满足:
- 存在产生正则捕获的源——
location正则、server_name、rewrite、if里的正则捕获组($1/$2或命名组)。 - 有一个使用正则模式的
map变量。 - 求值顺序上,捕获的引用在 regex map 变量之前被求值。典型写法如
"$1=$bodyvar=$1"这种把捕获和 map 输出变量拼进同一个字符串表达式的场景。
两条触发面:
- HTTP:regex
location+ regexmap - stream:
ssl_preread+ SNI + regexmap
受影响版本
- nginx Open Source:
0.9.6 ...)+$name),并让捕获只在持有该正则匹配的代码块内被引用。注意:研究人员指出这不能覆盖所有变体,升级仍是唯一彻底方案。升级后执行nginx -t && systemctl reload nginx让 worker 加载新二进制。
参考:
- nginx 安全公告:https://nginx.org/en/security_advisories.html
- 公开复现工程:https://github.com/jelasin/CVE-2026-42533