nginx可通过$ args变量配合if+正则直接过滤危险url参数,实现sql注入(如union select、sleep()、xss等攻击载荷的前置拦截,返回403,响应快、开销低。

直接在 Nginx 配置中过滤危险 URL 参数,核心是利用 $args 或 $request_uri 变量配合正则匹配,在请求抵达后端前完成识别与拦截。不依赖后端解析,响应快、开销低,适合作为第一道网关防护。
用 if + 正则精准拦截高危参数值
针对常见攻击载荷(如 SQL 注入、XSS、命令执行),可在 location 块内用 if 判断 $args 内容并返回 403:
- 拦截含
union select、sleep(、benchmark(等 SQL 注入特征:if ($args ~* "(union\s+select|sleep\(|benchmark\(|load_file\()") { return 403; } - 阻断常见 XSS 载荷参数:
if ($args ~* "(<script return></script> - 拒绝 base64 编码或 PHP 函数调用类参数:
if ($args ~* "(base64_|phpinfo|system\(|exec\(|passthru\()") { return 403; }
注意:$args 是解码后的查询字符串,不含 ?,仅包含 key=value 形式内容;若需匹配原始编码(如 %3Cscript),应改用 $request_uri。
用 map 预计算提升性能与可维护性
当规则较多时,避免多个 if 堆叠影响性能。推荐用 map 在 http 块中统一预判,生成布尔变量再集中判断:
- 定义敏感参数键名黑名单:
map $args $has_sensitive_key {<br> default 0;<br> ~*(?:^|&)(api_key|token|secret|password)= 1;<br>} - 定义危险值模式匹配:
map $args $has_dangerous_value {<br> default 0;<br> ~*(?:^|&)[^&]+=.*?(union\s+select|<script>}</script> - 在 location 中统一拦截:
if ($has_sensitive_key || $has_dangerous_value) { return 403; }
结合请求路径做上下文过滤
单纯参数匹配可能误杀,加入路径约束更精准。例如只对 API 接口拦截敏感参数:
- 限定仅对
/api/路径下生效:location ^~ /api/ {<br> if ($args ~* "(exec\(|cmd=|shell=)") { return 403; }<br> proxy_pass http://backend;<br>} - 排除白名单接口(如登录页允许
password):location = /login {<br> # 不做参数过滤<br> proxy_pass http://backend;<br>}
该 location 必须放在通用规则之前,确保优先匹配。
防止参数绕过与日志脱敏
攻击者常通过编码、空格、大小写混用绕过简单正则。同时需避免敏感参数落盘:
- 覆盖常见编码变体:
if ($request_uri ~* "(%3cscript|%20union%20select|%2575%256e%2569%256f%256e)") { return 403; } - 自定义日志格式,用
map替换敏感参数值:map $args $safe_args {<br> default $args;<br> ~*(?:^|&)(api_key|token)=([^&]*)(&?.*) "$1=***$3";<br>}<br>log_format main '$remote_addr - $remote_user [$time_local] "$request" $status $body_bytes_sent "$http_referer" "$http_user_agent" "$safe_args";'











