防止php文件类型欺骗需服务端校验二进制内容:用finfo_open验证真实mime类型,白名单过滤;结合getimagesize等二次解析;强制重命名并映射安全扩展名;上传目录须脱离web根或禁用脚本解析。

防止PHP文件类型欺骗,核心在于不信任任何客户端提供的信息——包括文件名、扩展名、Content-Type头,甚至前端JavaScript校验。攻击者能轻易伪造这些字段,真正有效的防护必须基于服务端对文件**二进制内容**的分析。
用finfo_open校验真实MIME类型
这是最可靠的第一道防线。它读取文件头部字节,识别实际格式,不受用户输入干扰。
- 调用finfo_open(FILEINFO_MIME_TYPE)获取文件的真实MIME类型
- 只允许白名单中的类型,例如image/jpeg、application/pdf、text/plain
- 明确拒绝text/html、application/x-php、application/x-sh等可执行或危险类型
- 注意:不要仅用$_FILES['file']['type'],它来自浏览器,完全不可信
结合内容解析做二次确认
单靠MIME识别仍有绕过可能(如构造“图片马”),需叠加内容层面验证。
- 对图像类文件,用getimagesize()检查是否真能被解析为有效图片
- 对PDF、Office文档等,可用专用库(如tcpdf、phpoffice/phpword)尝试轻量解析
- 对文本类文件,可扫描是否包含、eval(、system(等敏感关键词(需谨慎,避免误杀)
强制重命名并剥离原始扩展名
彻底切断用户对文件名和后缀的控制权,从源头消除欺骗路径。
- 完全丢弃$_FILES['file']['name'],不参与任何逻辑判断
- 生成新文件名:组合uniqid()、random_bytes()和时间戳,确保唯一性与不可预测性
- 扩展名严格由上一步确认的安全MIME类型映射得出(如image/png → '.png'),绝不采用用户提交的后缀
- 新文件名中过滤掉/、\、..等路径字符,防止目录遍历
配合存储与执行环境隔离
即使类型校验被绕过,也要确保上传文件无法被执行。
- 上传目录必须置于Web根目录之外(如/var/data/uploads/而非/var/www/html/uploads/)
- 若必须放在Web可访问路径下,需在Web服务器(如Nginx/Apache)中配置规则,禁止该目录下所有.php、.phtml等扩展名的脚本解析
- 配合disable_functions禁用exec、shell_exec等高危函数,降低后续危害
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











