防范nginx逻辑安全漏洞的关键在于控制请求解析与转发的确定性。需明确location匹配优先级,使用=或^~精确匹配敏感路径,正则匹配置于其后;显式拒绝非法路径;严格配置fastcgi参数并禁用php pathinfo;过滤畸形uri、规范路径处理;关闭冗余功能与模块,限制请求大小。

防范 Nginx 处理复杂请求时产生的逻辑安全漏洞,关键不在于堵住某个“特定漏洞”,而在于控制其请求解析与转发行为的确定性。这类漏洞(如 CVE-2019-18818、路径解析绕过、fastcgi_split_path_info 误配引发的代码执行等)本质是 Nginx 与后端(如 PHP-FPM)在路径语义理解上出现分歧,攻击者利用模糊路径(如 /a.jpg/.php、/script.php%00.jpg)触发非预期处理流程。
明确 location 匹配优先级与语义边界
Nginx 的 location 匹配顺序直接影响请求走向。模糊前缀匹配(location /api)可能意外覆盖精确路径或正则规则,导致本该被拦截的危险路径进入后端。
- 对管理接口、静态资源目录、上传路径等敏感路径,一律使用
=精确匹配(如location = /admin)或^~非正则前缀匹配,避免被后续正则规则干扰 - 所有通用正则匹配(
location ~ .php$)应放在精确/前缀匹配之后,并确保其作用域不覆盖不该解析为脚本的路径(例如禁止location ~ .php$匹配到/upload/image.jpg/.php) - 显式拒绝非法路径结构:添加
location ~ /.(ht|git|svn|conf|log|env)$ { deny all; }和location ~ [~[]{}$] { return 400; }
切断 Nginx 与后端的路径语义错位
PHP 的 cgi.fix_pathinfo=1 会主动“修复”路径,而 Nginx 若未严格截断,就会把原始 URI 全量传递过去,造成解析冲突。
- 在
fastcgi_params或 server 块中,强制设置fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;—— 不用$request_filename,杜绝路径拼接风险 - 禁用 PHP 的 pathinfo 行为:在 php.ini 中设
cgi.fix_pathinfo=0,让后端只认真实存在的 .php 文件 - 若必须支持 pathinfo,应在 Nginx 层做严格白名单校验,例如只允许
/index.php/xxx类型,拒绝含多点、空字节、编码字符的路径
限制并规范化输入路径本身
很多逻辑漏洞源于 Nginx 对畸形 URI 的宽容处理。主动过滤和标准化可大幅压缩攻击面。
- 用
if指令拦截超长、含危险字符或非法编码的 URI:if ($uri ~ "^/(.{512,}|.*[?#$*\%00-%08%0b%0c%0e-%1f].*)$") { return 400; } - 启用
underscores_in_headers on;并配合merge_slashes on;(默认开启),防止通过多余斜杠或下划线干扰解析 - 对上传目录单独配置:禁用脚本执行(
location ^~ /upload/ { location ~ .php$ { deny all; } }),且 root 路径需与 alias 严格区分,避免路径穿越
关闭冗余功能,收窄处理上下文
每个启用的模块都可能成为逻辑链上的薄弱环节。最小化运行时能力是防御纵深的基础。
- 全局关闭
server_tokens off;、autoindex off;,移除Server、X-Powered-By等响应头 - 禁用非必需模块:如无需 WebDAV、SSI、FLV 支持,编译时就不包含;运行时不加载
ngx_http_dav_module等 - 限制请求体大小与 URI 长度:
client_max_body_size 10m;、large_client_header_buffers 4 8k;,防畸形载荷触发解析异常











