不推荐在 alias 路径下构建防目录遍历策略——因为 alias 本身不具备路径合法性校验能力,它只做字符串替换,无法阻止 ../ 穿透;真正安全的做法是弃用 alias,改用 root + try_files 组合,若必须保留 alias,则需严格满足 location 与 alias 均以 / 结尾、叠加 try_files $uri =404 及全局拦截 .. 请求三重补丁。

不推荐在 alias 路径下构建防目录遍历策略——因为 alias 本身不具备路径合法性校验能力,它只做字符串替换,无法阻止 ../ 穿透。真正安全的做法是:**弃用 alias,改用 root + try_files 组合**。若因历史原因必须保留 alias,则需叠加多层防御补救,但风险仍高于 root 方案。
为什么 alias 天然不安全
alias 将 location 匹配部分直接替换为指定路径,不校验最终路径是否越界。例如:
- 配置
location /static { alias /var/www/assets; } - 请求
/static/../etc/passwd→ 替换后变成/var/www/assetsetc/passwd(路径拼接错误) - 若误配为
location /static/ { alias /var/www/assets; }(alias 缺末尾 /),请求/static//../etc/passwd可能被解析为/var/www/assets/../etc/passwd
这类问题不是配置疏忽,而是 alias 的设计机制决定的——它不参与文件系统路径归一化,也不检查 $uri 是否合法。
若坚持使用 alias,必须加的三道补丁
仅当无法迁移至 root 时才启用此方案,且每项都不可省略:
-
location 必须以 / 结尾,alias 值也必须以 / 结尾:如
location ^~ /static/ { alias /var/www/assets/; },避免 URI 后缀被错误拼接 - 强制用 try_files $uri =404:放在 alias 同级,确保只响应真实存在的文件,不回退、不尝试 index 或其他 fallback
-
在 server 块顶部拦截所有含 .. 或编码变体的请求:
if ($uri ~ "\.\.") { return 403; }if ($request_uri ~ "(\%2e\%2e|\.%2e|/\.\.|%2f\.\.)") { return 403; }
更可靠的选择:迁移到 root + try_files
这是 Nginx 官方文档与主流安全实践一致推荐的方式:
- 写法示例:
location ^~ /static/ { root /var/www; try_files $uri =404; } - 关键点:
location末尾带/,root值末尾不加/ - 请求
/static/../etc/passwd会被解析为/var/www/static/../etc/passwd,但try_files发现该路径不存在,直接返回 404,不会穿透 - 同时显式添加
autoindex off;,防止目录列表泄露
兜底加固:屏蔽敏感路径与隐藏头信息
无论用 alias 还是 root,以下两项都应全局启用:
-
敏感路径黑名单:在 server 块最上方添加
location ~ ^/(?:\.(?:git|env|htaccess)|config|backup|logs|phpmyadmin|owa) { return 403; } -
隐藏版本与服务器标识:
在 http 或 server 块中设置server_tokens off;,避免暴露 Nginx 版本供攻击者利用











