nginx 默认不清洗请求参数,需借助map+rewrite或lua-nginx-module在proxy_pass前标准化query/body;推荐用openresty的access_by_lua_block深度过滤、截断、解码并重设参数,兼顾get/post差异与日志审计。

在 Nginx 中使用 proxy_pass 时,Nginx 本身不提供参数清洗能力(如过滤非法字符、截断超长值、移除危险键名等),它默认原样转发请求行、头和查询参数。所谓“畸形请求参数的清洗代理”,需借助 Nginx 的模块能力,在请求进入 upstream 前做预处理。核心思路是:**在 proxy_pass 前拦截并标准化 query string 或 body,而非依赖后端处理异常输入。**
用 map + rewrite 清洗简单 query 参数
适用于对特定参数(如 id、q)做格式校验或替换。Nginx 的 map 指令可基于正则提取/转换变量,再通过 rewrite 重写 URI。
- 定义安全参数映射:只保留数字、字母、下划线、短横线,长度限制 64 字符
- 若参数不匹配,则设为空或默认值,避免透传恶意内容
- 示例配置:
default "";
~^[a-zA-Z0-9_-]{1,64}$ $arg_id;
}
server {
location /api/ {
# 若 id 不合法,清空它
rewrite ^(.*)$ $1?id=$safe_id&$args break;
proxy_pass http://backend;
}
}
用 lua-nginx-module 实现深度参数清洗
这是最灵活的方式。OpenResty(或编译了 lua 模块的 Nginx)可在 access_by_lua_block 中解析、过滤、重写请求参数,支持正则、白名单、黑名单、长度截断、URL 解码还原等。
- 读取
$args或ngx.req.get_uri_args()获取原始参数 - 遍历参数,对每个 key/value 应用清洗规则(例如:拒绝含
../、select、<script></script>的值) - 调用
ngx.req.set_uri_args(new_args)替换原始参数后继续流程 - 注意:需开启
lua_check_client_abort off避免中断干扰
用 nginx-http-subs-filter-module 过滤响应中的敏感内容(补充防护)
虽然不处理请求参数,但该模块可用于清洗后端返回中可能被注入的恶意内容(如 XSS payload),形成请求—响应双向净化闭环。配合 proxy_pass 使用时,建议仅用于 HTML 类响应,并谨慎配置正则以免误删正常文本。
规避常见陷阱
- 不要依赖 $args 直接拼接:它未解码,且多次 rewrite 可能导致重复编码;应优先用 lua 获取结构化参数
-
GET 和 POST 要区别对待:query string 用 map/rewrite/lua 处理;POST body 需用 lua 读取并重写(启用
lua_need_request_body on,但注意性能影响) - 避免在 location 中混用 rewrite 和 proxy_pass:break 和 last 行为易出错;推荐统一用 lua 做集中清洗
- 日志记录清洗前后对比:添加自定义 log_format 记录原始 $args 和清洗后变量,便于审计与调试











