php文件上传漏洞入口点需通过路由配置搜索upload/file/image/media定位控制器,检查$_files或框架上传方法调用;关键审计三缺失:扩展名白名单是否防双后缀、mime是否仅信客户端、文件头是否验证魔术字节;存储路径须非web可访问且禁执行,文件须随机重命名。

PHP框架中识别文件上传功能入口点
打开框架路由配置文件,搜索关键词 upload、file、image 或 media,快速定位控制器中处理上传请求的 action 方法。
进入对应控制器类,查找包含 $_FILES、$request->file()(Laravel)、$this->request->getUploadedFiles()(ThinkPHP)或 $this->uploadedFiles(Slim)的代码段——这些是服务端接收上传数据的明确信号。
重点检查是否调用 move_uploaded_file()、store()、saveAs() 等写入磁盘的操作,这是漏洞链的起点。
审计上传逻辑中的三处致命校验缺失
方法一:扩展名白名单是否真实生效
查看代码中是否仅用 pathinfo($filename, PATHINFO_EXTENSION) 提取后缀,并与硬编码数组比对;若使用 in_array(strtolower($ext), $whitelist) 且未过滤空格、点号、双扩展名(如 shell.php.jpg),则校验形同虚设。
方法二:MIME类型是否仅依赖客户端 header
【关键陷阱】 若代码中只判断 $_FILES['file']['type'] === 'image/jpeg',攻击者可篡改 HTTP 请求中的 Content-Type 字段绕过——该值完全由浏览器控制,服务端必须用 finfo_file() 或 getimagesize() 重新检测真实类型。
方法三:文件内容是否跳过魔术字节验证
对图片类上传,必须读取文件头 4–8 字节比对 PNG(\x89PNG)、JPG(\xff\xd8\xff)、GIF(GIF87a 或 GIF89a)等签名;若仅校验扩展名而放行伪造头部的 PHP 文件(如将 <?php phpinfo(); ?> 前插入 JPG 头),即可触发解析漏洞。
检查上传文件存储路径与执行权限
第一步:确认目标目录是否位于 Web 根目录下
搜索 $uploadDir = 'uploads/'、public/uploads、web/uploads 等路径拼接逻辑;若路径未以 /var/www/html/ 等绝对路径开头,且未通过 realpath() 校验,就存在目录遍历风险。
第二步:验证服务器是否禁止该目录执行脚本
在 Nginx 配置中查找 location ~ ^/uploads/.*\.(php|phtml|php3|php4|php5|php7|php8|phar|cgi|pl|py|jsp|asp|aspx|sh|bash|py|rb)$ { deny all; };Apache 则需检查 .htaccess 是否含 php_flag engine off 或 RemoveHandler .php。没有这两项配置,上传的 PHP 文件会被直接解析执行。
第三步:观察是否启用随机重命名
若保存逻辑为 $newName = $_FILES['file']['name'];,攻击者可构造 shell.php 直接覆盖已有文件;正确做法是用 uniqid() . '_' . mt_rand(1000, 9999) . '.' . $safeExt 生成不可预测文件名。
动态验证是否存在.htaccess解析劫持漏洞
手动上传一个名为 .htaccess 的文本文件,内容为:
AddType application/x-httpd-php .jpg<br>SetHandler application/x-httpd-php
再上传一个名为 test.jpg 的文件,内容为 <?php system($_GET['cmd']); ?>;访问 http://target.com/uploads/test.jpg?cmd=id,若返回系统命令执行结果,则说明 Apache 解析规则被成功覆盖,LFI+上传组合攻击成立。
注意:此测试需确保目标使用 Apache 且未禁用用户级 .htaccess 解析(AllowOverride All),Nginx 用户无需执行此步。
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











