PHP中的错误MIME类型检测
我有这样的代码:
<?php
if (isset($_POST)) {
$finfo = finfo_open(FILEINFO_MIME_TYPE);
$fileMime = finfo_file($finfo, $_FILES["file"]["tmp_name"]);
finfo_close($finfo);
echo $fileMime;
}
?>
<form method="post" enctype="multipart/form-data">
<input type="file" name="file">
<button type="submit">Upload</button>
</form>
在某些情况下,人们设法伪造MIME类型,它是一个带有application / octet-stream的.php文件,脚本将其检测为image / jpeg。
有什么办法解决这个问题,并检测正确的MIME类型?
谢谢!
它是一个.php文件
微软有条件适应你。 文件名不是由文件的内容决定的。 它只是一个人们经常用前者来表示后者的惯例。 在大多数Web服务器中使用相同的约定来将处理程序映射到文件。 因此,如果您足够愚蠢地信任用户提供的数据并将文件存储在文档根目录中,则用户可以将任意脚本上传到您的服务器。
正如Marc B所说,finfo_file读取文件并尝试将文件开头的可变数量的字节与已知文件格式的数据库进行匹配。
我猜想这个文件可能开始看起来像一个JPEG。
一旦网络服务器决定通过PHP处理程序推送内容,PHP将忽略外部的所有内容,并在<?php ... ?>
标记内执行任何操作。
看看十六进制编辑器中的文件,看看你找到了什么。
有什么办法解决这个问题,并检测正确的MIME类型?
为了什么目的? finfo_file()提供了一个最佳猜测。 如果你想确保文件是预期的格式,那么你需要专门设计用于识别和处理该格式的代码(例如,如果用户声明文件是JPEG格式,则使用imagecreatefromjpeg()加载它)。 如果您的系统依赖于文件扩展名映射到上传内容中的特定MIME类型,请在内容不匹配的情况下拒绝该内容。 正如Marc B已经指出的那样,大多数文件格式都是可以包含任何东西的复合结构(甚至一个ascii文本文件可以嵌入PHP)。 即一个文件可以是一个有效的JPEG和一个有效的PHP脚本。
PHP的设计就好像它是一种模板语言。 虽然最初的想法是在HTML中嵌入动态内容:
<p>Hello, <?=htmlspecialchars($name)?>!</p>
...你当然可以将PHP代码嵌入你想要的任何东西中; PHP解释器并不关心这一点。 真正使文件成为PHP脚本的唯一事实就是它已被提供给PHP解释器。
finfo_file()
只是利用数据库来查找特定的签名。 如果你有一个普通的JPEG文件,它会以一个PHP块结束,它会被报告为图片。
总结一下:
上一篇: False MIME type detection in PHP
下一篇: PHP 5.3.5 fileinfo() MIME Type for MS Office 2007 files