最有效防护是在上传目录 location 块中用前缀匹配禁用脚本执行,如 location ^~ /upload/ { location ~ \.php$ { return 403; } },并扩展拦截 pl/py/sh/cgi 等后缀,配合 server 级 if 拦截 %00 编码绕过,避免 if 写在 location 内或全局误拦合法入口。

直接在对应目录的 location 块中禁用脚本解析,是最有效、最底层的防护方式。关键不是“阻止访问”,而是“不让服务器执行它”,尤其针对上传目录或静态资源区里可能混入的恶意 PHP、Shell 等脚本。
对上传目录做硬性 PHP 隔离
比如网站有 /upload/ 目录用于用户上传图片,但攻击者可能上传 shell.php 并尝试访问执行。此时不能只靠后缀黑名单,而应从路径层面切断执行能力:
- 使用前缀匹配(
^~)确保优先级最高,避免被正则 location 覆盖 - 在该 location 内嵌套一个专门匹配
.php的子块,并拒绝所有请求 - 不依赖
deny all就够了,更推荐用return 403明确返回禁止状态
示例配置:
location ^~ /upload/ {
location ~ \.php$ {
return 403;
}
}
扩展覆盖其他可执行脚本类型
除了 PHP,还需考虑 Perl、Python、Shell 等常见服务端脚本。可根据实际环境补充:
-
location ~ \.(php|pl|py|sh|cgi)$ { return 403; }—— 统一拦截多种后缀 - 若站点完全不用 CGI,可全局禁用:
location ~ \.cgi$ { return 403; } - 对敏感目录如
/configs/、/data/,直接禁止所有脚本执行更稳妥
配合空字节与编码绕过防护
攻击者常通过 %00 截断、双写编码等方式绕过简单后缀检查。因此需在 server 级别提前拦截异常路径模式:
- 放在所有
location块之前(非内部),用if检查$request_uri - 拦截
%00.php、.jpg%00/.php等典型变体 - 例如:
if ($request_uri ~ "%00") { return 403; }
避免常见配置陷阱
这类防护容易因 Nginx 匹配机制失效:
- 不要把
if写在location内部——Nginx 的if在 location 中执行上下文受限,可能跳过 - 不要仅靠
location ~ \.php$ { deny all; }全局禁用——这会同时拦掉合法后台入口 - 确认
fastcgi_pass或proxy_pass不在被保护目录的 location 中意外启用











