Nginx目录遍历防护需前置拦截:server块开头用if匹配非法URI和uri路径并返回403;静态资源禁用alias,改用root+try_files;全局关闭autoindex,黑名单敏感路径前缀;敏感文件移出Web根目录,配合internal和X-Accel-Redirect控制访问。

在 Nginx 的 location 块中做目录遍历防护,关键不是“等请求进来再判断”,而是让越界路径根本无法匹配到文件系统——所有防御动作必须前置、精准、不依赖后端。
在 server 块顶层统一拦截非法路径模式
规则必须写在 server 块最开始(所有 location 之前),利用 Nginx 请求解析早期阶段的匹配机制:
-
if ($request_uri ~ "(\.\.\/|\/\.\.|%2e%2e|\.%2e|\/%2e%2e)") { return 403; }——覆盖原始请求里的编码和混合写法,如%2e%2e/..或./../ -
if ($uri ~ "\.\.") { return 403; }——拦截解码归一化后的路径,防绕过 -
if ($uri ~ "//") { return 403; }——双斜杠易干扰路径标准化,是常见绕过手法
静态资源 location 必须用 root + try_files,禁用 alias
alias 是目录遍历高危指令,它只做字符串替换,不校验路径合法性。例如:location /static { alias /data/files; } 遇到 /static/../etc/passwd 可能拼出 /data/filesetc/passwd。
- ✅ 正确写法:
location /static/ { root /data; try_files $uri =404; } - 注意:
location末尾带/,root路径末尾不加/ -
try_files $uri =404强制只响应真实存在的文件,不回退、不列目录、不暴露结构
显式关闭 autoindex 并屏蔽敏感路径前缀
即使路径没穿越成功,直接访问 /.env 或 /uploads/ 也可能泄露信息:
- 全局设
autoindex off;(放在server或http块中),避免继承开启 - 在
server块靠前位置添加黑名单:location ~ ^/(?:\.(?:git|env|htaccess)|config|backup|logs|phpmyadmin) { return 403; } - 正则以
^/开头锚定,防止误杀正常路径中的子串;且该规则必须在通用location ~ \.php$等之前,否则会被覆盖
敏感目录改用 internal + 后端控制分发
对需要有条件访问的文件(如登录后下载),不能靠 URL 暴露物理路径:
- 把敏感文件移出 Web 根目录,例如存到
/var/www/private/uploads/ - Nginx 中配置:
location /download/ { internal; alias /var/www/private/; } - 后端脚本(PHP/Python)做权限校验后,返回
X-Accel-Redirect: /download/real_file.pdf,Nginx 内部重定向发送,外部无法直连


















