使用不存在的正则表达式捕获组¶
Gixy 检查 ID:invalid_regex
在 NGINX 指令(如 rewrite 或 if 条件)中使用带有捕获组的正则表达式时,您可以在替换字符串或后续指令中使用 $1、$2 等引用这些捕获的组。但是,如果您引用的捕获组在正则表达式模式中不存在,NGINX 会将其视为空字符串,这可能导致意外行为。
如何发现?¶
您应该检查:
- rewrite 指令,其中替换字符串引用了正则表达式模式中不存在的捕获组(例如 $1、$2)
- if 块内的 set 指令,引用了 if 条件正则表达式模式中的捕获组
- 非捕获组如 (?:...) 或内联修饰符如 (?i),它们不会创建编号的捕获组
示例¶
示例 1:非捕获的内联修饰符¶
有问题的配置:
server {
location / {
# (?i) 是大小写不敏感标志,不是捕获组
rewrite "(?i)/" $1 break;
}
}
问题: 模式 (?i)/ 使用 (?i) 启用大小写不敏感匹配,但它不创建捕获组。$1 引用将为空。
修复:
server {
location / {
# 添加括号创建捕获组
rewrite "(?i)/(.*)" /$1 break;
}
}
示例 2:缺失捕获组¶
有问题的配置:
server {
location / {
rewrite "^/path" $1 redirect;
}
}
问题: 模式 ^/path 没有捕获组,所以 $1 将为空。
修复:
server {
location / {
# 要么删除不必要的 $1 引用
rewrite "^/path" /newpath redirect;
# 要么在需要时添加捕获组
rewrite "^/path/(.*)$" /newpath/$1 redirect;
}
}
示例 3:引用错误的组号¶
有问题的配置:
server {
location / {
# 模式只有 1 个捕获组,但引用了 $2
rewrite "^/(.*)$" /$1/$2 break;
}
}
问题: 模式只有一个捕获组 (.*),但替换引用了 $1 和 $2。$2 将为空。
修复:
server {
location / {
# 如果需要,添加第二个捕获组
rewrite "^/([^/]+)/(.*)$" /$2/$1 break;
# 或删除无效引用
rewrite "^/(.*)$" /prefix/$1 break;
}
}
示例 4:if 块中的 Set¶
有问题的配置:
server {
location / {
if ($uri ~ "^/path") {
set $x $1; # $1 不存在
}
}
}
问题: if 条件中的正则表达式模式没有捕获组,所以 $1 是未定义的。
修复:
server {
location / {
if ($uri ~ "^/path/(.*)$") {
set $x $1; # 现在 $1 包含捕获的值
}
}
}
我能做什么?¶
- 在正则表达式模式中添加捕获组,如果您需要引用匹配字符串的部分
- 删除不必要的捕获组引用,如果您实际上不需要它们
- 使用正确的组号 — 记住组编号从 1 开始,NGINX 中没有
$0 - 记住非捕获组不创建引用 — 像
(?:...)、(?i)、(?=...)这样的模式不创建编号组 - 测试您的正则表达式模式,确保它们捕获您期望的内容
加固 NGINX,使用维护的 RPM
使用 GetPageSpeed 提供的 NGINX Extras 在 RHEL/CentOS/Alma/Rocky 上获取持续更新的 NGINX 与模块。 了解更多.