文档首页> 技术教程> 上传目录禁止执行 PHP 的两种写法

上传目录禁止执行 PHP 的两种写法

发布时间:2026-04-05 16:59        更新时间:2026-04-06 07:45
上传目录一旦能执行 PHP,等于把一块服务器执行权交了出去,攻击者把脚本伪装成图片传上来,就能直接在服务器上运行代码,后果远不止页面被篡改。程序侧的校验再严,Web 层这道兜底也必须有,校验逻辑可能有漏洞,拦截规则是死的,不会失手。 为什么正则要写全变体 绕过上传校验的常见手法不少:双写后缀、大小写变换、利用老版本 PHP 的截断符,最终落地的文件可能是 .php5、.phtml、.Php 这类变体。所以 Web 层拦截的正则要把常见 PHP 变体一网打尽,并且不分大小写。 Nginx 写法一:正则拒绝 在站点 server 块加: location ~* ^/uploads/.*\.(php|php5|php7|phtml)$ { deny all; } 命中 uploads 下的 PHP 类请求一律拒绝,返回 403。~* 修饰符本身已忽略大小写。注意正则 location 之间的匹配顺序,这条配置所在的位置要能被请求命中,改完 nginx -t 加 reload。 Nginx 写法二:整目录收口 更稳的做法是把 uploads 整个目录限定为纯静态: location ^~ /uploads/ { location ~ \.php$ { return 403; } expires 7d; } ^~ 前缀匹配优先于正则,先把 uploads 圈进独立范围,内层再拦 .php,顺带给静态文件加个过期时间。两种写法选一种即可,同时存在时留意嵌套关系,别互相抢匹配。更进一层的隔离是让上传走独立域名或对象存储,主域根本不代理上传目录,执行面直接消失,有条件实现这个形态的业务优先这么做。 Apache 的处理 Apache 2.4 写在站点配置或 .htaccess: Require all denied Nginx 反代加 Apache 后端的混合架构两条都要配,只配前面一层,请求绕过反代直连后端时就没防住了。 验证是否生效 往 uploads 目录放一个内容为