nginx可通过正则匹配$request_uri和$args直接阻断sql注入、xss等攻击,如匹配union select、script、javascript等高危模式并返回403,实现零延迟网关防护。

直接在 Nginx 配置中匹配并阻断含敏感字符或 SQL 注入指纹的 URL,是成本最低、响应最快的一道网关防线。它不解析语义,也不依赖后端,而是在请求路由阶段就识别典型攻击特征并立即拦截。
精准拦截 URL 和查询参数中的高危模式
攻击者常把恶意内容藏在 $request_uri(原始请求路径+参数)或 $args(解码后的查询参数)里。Nginx 可用 if + ~* 进行不区分大小写的正则匹配:
- 封禁 SQL 注入常见关键字:
if ($args ~* "(union\s+select|select.*from|insert\s+into|drop\s+table|'|--|#|/\*|\bexec\b|\bsystem\b)") { return 403; } - 拦截 XSS 和脚本载荷:
if ($request_uri ~* "(<script return></script> - 阻断目录遍历尝试:
if ($request_uri ~* "(\.\./|/%2e%2e|/\.%2e|//)") { return 403; }
按路径粒度启用差异化防护
不是所有接口都需要同等强度的过滤。比如仅对 API 路径开启 SQL 检测,能减少误杀和性能损耗:
- 在
location /api/块内单独加规则,避免影响静态资源 - 使用
map指令预标记风险,比堆叠多个if更高效:map $args $sql_flag {<br> ~*(union|select|insert) 1;<br> default 0;<br>}
再统一判断:if ($sql_flag) { return 403; } - 对
/login或/search等高频入口,可额外加入长度限制或字符白名单逻辑
防御编码绕过与混合变形
攻击者会用 URL 编码、大小写混写、注释符分隔等方式绕过简单匹配。需覆盖常见变体:
- 同时检查编码与明文:
%27(单引号)、%3C(%23(#)等 - 用
\b锚定单词边界,避免误杀user_id中的id;用\s+匹配空格变体,如union%20select或union/**/select - 慎用
if在location外大量出现——应优先放在 server 块顶层或关键 location 内,且确保无重复匹配逻辑
配合基础安全配置形成闭环
单纯字符拦截不能替代整体防护,需与其他机制协同:
- 禁用目录列表:
autoindex off;,并用try_files $uri =404;替代裸root或危险的alias - 屏蔽敏感路径前缀:
location ~ ^/(?:\.git|\.env|config\.php|phpmyadmin|wp-admin) { return 403; } - 校验 Host 头防虚拟主机探测:
if ($host !~ ^(example\.com|www\.example\.com)$) { return 444; } - 记录被拦截请求的 IP 和 URI 到独立日志,便于溯源分析











