使用 Nginx 内置变量匹配 SQL 注入特征
在 nginx 中配置安全过滤拦截 sql 注入,最直接且高效的方法是利用 if 指令结合正则表达式,对 $request_uri(请求 uri)或 $args(查询参数)进行模式匹配。当检测到包含常见 sql 关键字(如 union、sleep、drop)或特殊字符组合时,立即返回 403 forbidden 状态码以阻断请求。这种方法无需依赖外部模块,通过简单的正则规则即可实现基础的防护,适用于大多数 web 应用的前置过滤场景。

server {
listen 80;
server_name example.com;
location / {
# 检查 URI 和查询参数中的 SQL 注入特征
if ($request_uri ~* "(union|select|insert|update|delete|drop|alter)\s") {
return 403;
}
if ($args ~* "(union|select|insert|update|delete|drop|alter)\s") {
return 403;
}
# 其他业务逻辑
proxy_pass http://backend;
}
}
上述配置展示了如何在 location 块中嵌入 if 判断。首先,$request_uri 包含了路径和查询字符串,而 $args 仅包含查询字符串部分。通过 ~* 操作符进行不区分大小写的正则匹配,可以捕获常见的 SQL 注入尝试。一旦匹配成功,Nginx 会立即执行 return 403,终止后续处理并返回禁止访问的错误页面。这种机制简单直接,能够有效拦截基于关键字的初级注入攻击。
针对特定参数值进行精细化过滤
除了全局匹配,有时需要针对特定的 GET 或 POST 参数进行更精细的控制。例如,如果某个接口接受用户 ID 作为参数,可以通过正则表达式严格限制其格式,只允许数字或特定字符,从而排除包含 SQL 语法的非法输入。这种方式比宽泛的关键字匹配更精准,能减少误杀正常请求的概率,同时提高安全性。通过 $arg_id 这样的变量可以直接获取指定参数的值,便于实施白名单策略。

server {
listen 80;
server_name example.com;
location /api/user {
# 假设有一个名为 id 的参数
# 只允许纯数字,拒绝任何非数字字符
if ($arg_id !~ ^[0-9]+$) {
return 403;
}
# 或者检查是否存在明显的注入 payload
if ($arg_id ~* "('|%27|--|%23)" ) {
return 403;
}
proxy_pass http://backend;
}
}
在这个例子中,我们针对 /api/user 路径下的 id 参数进行了严格校验。$arg_id 变量提取了 URL 中 ?id=... 的值。第一个 if 语句使用 !~ 操作符确保 id 只包含数字,任何字母、符号或空格都会导致请求被拒。第二个 if 语句则进一步检查是否包含单引号、双横线等常见注入符号。这种基于参数值的过滤方式,能够更有效地保护后端数据库免受针对性攻击,同时保持对合法数据的兼容。
如何处理被拦截请求的日志记录与监控
当 Nginx 成功拦截 SQL 注入尝试时,仅仅返回 403 是不够的,还需要确保这些安全事件被记录下来以便后续分析。通过在 log_format 中定义自定义日志格式,可以将被拦截的请求详情写入专用日志文件。这有助于安全团队识别攻击来源、频率和手法,进而调整防火墙规则或优化 WAF 策略。此外,结合监控系统,可以实现实时告警,提升响应速度。
# nginx.conf 主配置部分
log_format security '$remote_addr - $remote_user [$time_local] '
'"$request" $status $body_bytes_sent '
'"$http_referer" "$http_user_agent" '
'uri=$request_uri args=$args';
server {
listen 80;
server_name example.com;
access_log /var/log/nginx/security.log security;
location / {
if ($request_uri ~* "(union|select|insert|update|delete|drop|alter)\s") {
return 403;
}
proxy_pass http://backend;
}
}
上述配置定义了一个名为 security 的日志格式,它记录了客户端 IP、时间戳、请求方法、URI、参数以及状态码等信息。将该格式应用于 access_log 指令,所有经过该服务器的请求都会被记录到 /var/log/nginx/security.log 文件中。对于被拦截的请求,虽然它们不会到达后端应用,但会在 Nginx 层面留下痕迹。通过分析这些日志,可以发现潜在的扫描行为或攻击模式,为后续的安全加固提供数据支持。这种日志记录机制是构建完整安全防护体系的重要一环,确保每一次拦截都有据可查。











