白名单防护是php文件上传最可靠的基础策略,需服务端校验真实扩展名、mime类型及文件头魔术字节,并配合重命名、目录隔离、脚本禁用和日志审计。

白名单防护是PHP文件上传安全中最可靠的基础策略——它不试图识别所有危险类型,而是只接受明确已知安全的类型,从源头切断恶意文件进入的可能。
只允许特定扩展名
扩展名校验必须在服务端完成,且仅使用白名单(如['jpg', 'png', 'gif', 'pdf']),严禁用黑名单。需注意:
- 用
pathinfo($filename, PATHINFO_EXTENSION)提取真实扩展名,再转为小写统一比对 - 过滤掉扩展名中可能存在的空字节(
\0)或路径分隔符(/、\) - 避免直接信任
$_FILES['file']['name'],攻击者可伪造任意名称
结合真实MIME类型验证
浏览器提交的$_FILES['file']['type']极易被篡改,必须用PHP内置函数做二次确认:
- 对图片类文件,调用
getimagesize($tmp_file),返回非false才视为有效 - 对通用文件,使用
finfo_open(FILEINFO_MIME_TYPE)获取服务器实际解析出的MIME类型 - 将结果与预设白名单(如
['image/jpeg', 'application/pdf'])严格比对
检查文件内容“魔术字节”
即使扩展名和MIME都匹配,文件头仍可能被篡改。读取文件前几个字节,验证是否符合宣称格式:
- JPEG文件开头应为
FF D8 FF,PNG为89 50 4E 47 - 可用
fopen + fread($fp, 4)读取头部,再用bin2hex()转换比对 - 此步骤能识别“图片马”——表面是图片、内嵌PHP代码的恶意文件
白名单必须配合其他措施才真正有效
单独的白名单不能解决全部风险,需与以下操作协同:
- 上传后立即重命名文件,用
uniqid() . mt_rand()等生成不可预测的新名 - 把文件存到Web根目录之外(如
/var/uploads/),通过PHP脚本控制访问 - 确保上传目录在Web服务器(Nginx/Apache)中禁用脚本执行权限
- 记录每次上传的原始名、大小、类型、IP和时间,便于审计追踪
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











