应禁用 alias 做静态资源映射,因其不校验路径合法性易导致目录遍历;推荐改用 root + try_files 实现硬隔离,并配合 autoindex off、拦截穿越字符及敏感路径前缀等加固措施。

别用 alias 做静态资源映射——这是最直接有效的安全策略。它天生不适合边界控制,强行“修”配置不如换用更安全的机制。
为什么 alias 是目录遍历高危区
alias 执行的是纯字符串替换,不校验路径合法性,也不做归一化处理。比如:
location /static { alias /data/files; }- 请求
/static/../etc/passwd→ 替换后变成/data/filesetc/passwd - Nginx 真的会去读这个文件,只要权限允许
哪怕加了尾斜杠(/static/),若后端路径未标准化或存在编码绕过(如 %2e%2e),依然可能被击穿。
正确做法:用 root + try_files 替代 alias
把资源放在统一父目录下,靠 location 路径前缀和 try_files 实现硬隔离:
- 写成
location /static/ { root /var/www; try_files $uri =404; } -
root指向父目录,末尾不加斜杠 -
location必须以/结尾,确保匹配严格 -
try_files $uri =404强制只响应真实存在的文件,不存在就返回 404,不回退、不列目录
必须配套的三项加固动作
-
全局禁用目录列表:在
http或server块中写autoindex off;,防止任何 location 意外开启 -
顶层拦截穿越字符:在
server块开头(不在任何 location 内)加:if ($uri ~ "\.\.") { return 403; }if ($request_uri ~ "(\.\.\/|\/\.\.|%2e%2e|\.%2e)") { return 403; }if ($uri ~ "//") { return 403; } -
屏蔽敏感路径前缀:在通用 location(如
location ~ \.php$)之前加:location ~ ^/(?:\.(?:git|env|htaccess)|config|backup|logs|phpmyadmin) { return 403; }
如果真没法不用 alias,最低限度补救
仅限遗留系统临时过渡,且需满足全部条件:
- location 必须以
/结尾(如/static/) - alias 路径末尾也必须带
/(如alias /data/files/;) - 紧随其后加
internal;,禁止外部直接访问,仅允许内部重定向调用 - 仍要配合上述
if拦截和autoindex off
但这只是降低风险,不是根除。长期请迁移至 root + try_files 方案。











