文件魔数是文件头的十六进制标识,用于准确识别文件类型,如JPG为FFD8FF、PNG为89504E47;PHP可通过fread读取文件前16字节并转换为十六进制,再与标准魔数比对,结合finfo获取MIME类型、限制目录执行权限及重命名文件等措施,可有效防止恶意文件上传。

上传文件时仅靠扩展名判断类型很容易被绕过,攻击者可以将恶意脚本伪装成图片或其他安全格式。为提高安全性,PHP应通过读取文件的“魔数”(即文件头信息)来识别文件的真实类型。
文件魔数是文件开头的一段十六进制数据,用于标识文件的真实格式。例如:
这些数据无法通过简单修改后缀名改变,因此更可靠。
可以通过 fread() 读取文件前几个字节,并与已知魔数比对:
立即学习“PHP免费学习笔记(深入)”;
function checkFileMimeType($filePath) {
$handle = fopen($filePath, 'rb');
if (!$handle) {
return false;
}
// 读取前16个字节
$bin = fread($handle, 16);
fclose($handle);
$hexValues = unpack('H*', $bin);
$hex = strtoupper($hexValues[1]);
// 提取前几位进行匹配
$header = substr($hex, 0, 8);
if (strpos($header, 'FFD8FF') === 0) {
return 'image/jpeg';
} elseif (strpos($header, '89504E47') === 0) {
return 'image/png';
} elseif (strpos($header, '47494638') === 0) {
return 'image/gif';
} elseif (strpos($header, '25504446') === 0) {
return 'application/pdf';
}
// 可继续添加其他类型...
return 'unknown';
}
// 使用示例
$uploadedFile = $_FILES['file']['tmp_name'];
$mimeType = checkFileMimeType($uploadedFile);
if ($mimeType === 'image/jpeg' || $mimeType === 'image/png') {
// 允许上传
} else {
die('文件类型不合法!');
}
建议组合以下方式提升安全性:
<font face="Courier New">
$finfo = finfo_open(FILEINFO_MIME_TYPE);
$mimeType = finfo_file($finfo, $filePath);
finfo_close($finfo);
</font>某些图像编辑软件可能在文件头部添加额外数据(如元信息),影响读取。建议多读取一些字节并跳过常见干扰位,或结合多种方法交叉验证。
不要完全依赖 $_FILES['type'],该值由客户端提供,极易伪造。
基本上就这些,魔数检测虽不能百分百防御所有伪装,但能有效拦截大多数基础攻击手段。配合其他措施,可大幅提升文件上传的安全性。
以上就是php如何上传文件校验文件头信息_php读取文件魔数判断真实类型防伪装的详细内容,更多请关注php中文网其它相关文章!
PHP怎么学习?PHP怎么入门?PHP在哪学?PHP怎么学才快?不用担心,这里为大家提供了PHP速学教程(入门到精通),有需要的小伙伴保存下载就能学习啦!
Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号