修复php文件上传漏洞需建立分层防御:强制重命名(如md5(uniqid().rand()).'.jpg')、硬编码后缀、finfo校验真实mime类型、图片重绘清除末尾代码、上传目录禁执行并路径隔离,杜绝用户输入参与路径拼接。

修复PHP文件上传漏洞,关键不是加一两个判断,而是建立一套分层防御机制:从文件名、内容、存储到执行环境,每个环节都不能信任用户输入。
强制重命名 + 白名单后缀
绝不能用$_FILES['name']或pathinfo($name, PATHINFO_EXTENSION)直接取后缀。攻击者用shell.php.jpg、1.php::$DATA、test.PHP等写法可轻松绕过。
- 生成唯一文件名,例如:
md5(uniqid() . rand()) . '.jpg' - 后缀必须硬编码(如
'.jpg'),不从原始名中提取 - 禁用大小写混用、多点、NTFS流、空格、Unicode点号等绕过形式
用finfo校验真实MIME类型
$_FILES['type']和前端Content-Type完全可伪造,毫无防护价值。
- 调用
finfo_file(finfo_open(FILEINFO_MIME_TYPE), $tmp_file)读取文件头 - 只允许白名单类型,例如
image/jpeg、image/png、application/pdf - 拒绝
text/plain、application/x-php、application/octet-stream等模糊类型
图片类文件必须重绘
getimagesize()或exif_imagetype()只检查头部,无法识别图片末尾嵌入的PHP代码(即“图片马”)。
- 用
imagecreatefromjpeg()或imagecreatefrompng()加载原图 - 用
imagejpeg()或imagepng()全新输出,丢弃所有元数据和尾部数据 - 保存的是新生成的二进制流,不是原始
$tmp_name
上传目录禁执行 + 路径隔离
即使文件本身安全,配置不当仍会导致恶意代码被执行。
- Apache下,在上传目录放
.htaccess:<files> SetHandler default-handler </files> - Nginx下,在对应
location块中添加:deny all;或fastcgi_param SCRIPT_FILENAME ""; - 上传目录不要放在Web根目录下;若必须放在
public/内,确保其无执行权限 - 禁止任何用户输入参与路径拼接,保存路径应为绝对硬编码,如
ROOT_PATH . '/uploads/'
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











