最直接有效的防目录遍历做法是禁用alias做静态资源映射;因其仅机械替换URI前缀且不校验路径合法性,易被../绕过,应改用root+try_files,并配合禁用autoindex、拦截..及敏感路径前缀。

别用 alias 做静态资源映射,这是最直接有效的防目录遍历做法。Nginx 的 alias 指令本身不校验路径合法性,只做机械字符串替换,极易被 ../ 绕过,属于高危配置项。
为什么 alias 容易引发路径遍历
alias 的行为是“整段替换”:匹配到的 URI 前缀被完全替换成目标路径。例如:
location /static { alias /data/files; }- 请求
/static/../etc/passwd→ Nginx 把/static替换为/data/files,得到/data/filesetc/passwd→ 成功读取系统文件
哪怕加了斜杠(如 location /static/ { alias /data/files/; }),仍可能因 URI 归一化、编码变体(%2e%2e)或双斜杠干扰而失效。
正确替代方案:root + try_files
用 root 搭配 try_files,从语义和执行机制上杜绝越界可能:
location /static/ { root /data; try_files $uri =404; }-
root指向父目录,location必须以/结尾(如/static/) - Nginx 会拼接
/data + /static/ + 请求路径,物理路径严格限定在/data/static/下 -
try_files $uri =404强制只响应真实存在的文件,不存在就 404,不回退、不列目录、不尝试其他匹配
必须同步做的安全加固
单靠改用 root 不够,还需补全以下几项:
-
全局禁用目录列表:在
http或server块中写autoindex off; -
拦截含 .. 的原始请求:在
server块顶层(不在任何location内)加:if ($uri ~ "\.\.") { return 403; }if ($request_uri ~ "(\.\.\/|\/\.\.|%2e%2e|\.%2e|\/%2e%2e)") { return 403; }if ($uri ~ "//") { return 403; } -
屏蔽敏感路径前缀:在
server块靠前位置(必须早于通用location ~ \.php$等)加:location ~ ^/(?:\.(?:git|env|htaccess)|config|backup|logs|phpmyadmin|owa) { return 403; }
额外建议:敏感文件不放 Web 根下
真正重要的文件(如配置、日志、上传临时件)应存放在 Nginx 无法直接访问的路径,比如 /var/www/private/。需要对外提供时,走后端权限校验 + X-Accel-Redirect 内部转发,彻底切断直连可能。


















