PHP文件上传漏洞源于开发疏忽,核心风险在于客户端可控的$_FILES['type']和文件扩展名校验失效,需强制重命名、白名单校验、执行隔离三者缺一不可。

PHP 文件上传漏洞本身不是功能,而是因开发疏忽导致的不安全行为;直接利用它上传木马属于违法行为,且现代 PHP 环境(如开启 open_basedir、禁用 eval/assert、禁用危险函数)和 Web 服务器配置(如 Nginx 禁止执行上传目录下的 PHP)已大幅压缩此类攻击面。
为什么 $_FILES 直接保存就可能出问题
开发者常误以为检查 $_FILES['file']['type'] 或文件后缀就足够,但这两个值均由客户端控制,完全不可信。浏览器可随意伪造 Content-Type,也能把 shell.php 改名为 shell.jpg 提交。
-
$_FILES['file']['type']是浏览器发送的 MIME 类型,例如image/jpeg,服务端未校验时可被绕过 - 仅依赖
pathinfo($filename, PATHINFO_EXTENSION)取扩展名,无法防御shell.php.jpg或shell.php%00.jpg(在旧版 PHP 中触发空字节截断) - 未重命名文件,保留原始名可能导致路径遍历(如
../../.htaccess)或覆盖关键文件
真实环境中绕过常见校验的典型方式
这些是渗透测试中验证逻辑缺陷的思路,不是操作指南——生产环境必须杜绝所有此类路径。
- 使用
getimagesize()验证图片文件头,但若只校验一次且未配合 MIME + 扩展名白名单,仍可能被构造“图片马”绕过(如在 JPEG 文件末尾追加 PHP 代码) - 用
finfo_open(FILEINFO_MIME_TYPE)检测实际内容类型,比$_FILES['type']可靠,但仍需配合扩展名白名单和重命名 - Apache 环境下,若上传目录存在
.htaccess且允许覆盖,攻击者可能上传含AddType application/x-httpd-php .xxx的文件,再上传shell.xxx触发解析
安全上传必须做的三件事
缺一不可,少做任何一项都可能让防护形同虚设。
在原版的基础上做了一下修正:增加1st在线支付功能与论坛用户数据结合,vip也可与论坛相关,增加互动性vip会员的全面修正评论没有提交正文的问题特价商品的调用连接问题删掉了2个木马文件去掉了一个后门补了SQL注入补了一个过滤漏洞浮动价不能删除的问题不能够搜索问题收藏时放入购物车时出错点放入购物车弹出2个窗口修正定单不能删除问题VIP出错问题主题添加问题商家注册页导航连接问题添加了导航FLASH源文
立即学习“PHP免费学习笔记(深入)”;
- 强制重命名:用
uniqid() . bin2hex(random_bytes(8))生成唯一文件名,彻底丢弃客户端传来的$_FILES['file']['name'] - 白名单校验:只允许
['jpg', 'jpeg', 'png', 'gif']等明确安全的扩展名,且通过strtolower(pathinfo($new_name, PATHINFO_EXTENSION))获取,不依赖客户端输入 - 隔离执行:将上传目录置于 Web 根目录之外(如
/var/www/uploads/→ 移到/var/data/uploads/),或在 Web 服务器配置中禁止该目录下执行脚本(Nginx 中用location ~ \.php$ { deny all; })
$upload_dir = '/var/data/uploads/';
$allowed_exts = ['jpg', 'jpeg', 'png', 'gif'];
$file_info = pathinfo($_FILES['file']['name']);
$ext = strtolower($file_info['extension'] ?? '');
if (!in_array($ext, $allowed_exts)) {
die('Invalid file extension');
}
$new_name = uniqid() . '.' . $ext;
move_uploaded_file($_FILES['file']['tmp_name'], $upload_dir . $new_name);
真正难防的是业务逻辑层的盲点:比如允许用户上传 ZIP 并服务端解压,却未限制解压路径;或上传 SVG 文件,而 SVG 内可嵌入 标签触发 XSS。这类问题不会出现在“上传木马”的教科书式场景里,但更隐蔽、更常被忽略。










