我有这段代码:
<?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类型?
谢谢!
答案 0 :(得分:1)
这是一个.php文件
微软让你很好。文件名不是由文件内容决定的。它只是一个人们经常使用前者来表示后者的惯例。在大多数Web服务器中使用相同的约定来将处理程序映射到文件。因此,如果您足够信任用户提供的数据并将文件存储在文档根目录中,那么用户可以将任意脚本上传到您的服务器。
正如Marc B所说,finfo_file读取文件并尝试将variable number of bytes at the beginning of the file与已知文件格式的数据库进行匹配。
我猜这个文件可能看起来像JPEG。
一旦网络服务器决定通过PHP处理程序推送内容,PHP将忽略所有内容,并执行<?php ... ?>
标记内的任何内容。
在十六进制编辑器中查看文件,看看你找到了什么。
有没有办法解决这个问题并检测正确的MIME类型?
到底是什么? finfo_file()提供了最好的猜测。如果您想确保文件具有预期的格式,那么您需要专门设计用于识别和处理该格式的代码(例如,如果用户断言文件是JPEG,则使用imagecreatefromjpeg()加载它)。如果您的系统依赖于映射到上载内容中特定mimetype的文件扩展名,请拒绝该内容(如果不匹配)。正如Marc B已经指出的那样,大多数文件格式都是复合结构,几乎可以包含任何东西(甚至ascii文本文件也可以嵌入PHP)。即文件可以是有效的JPEG和有效的PHP脚本。
答案 1 :(得分:1)
PHP被设计为好像它是一种模板语言。虽然最初的想法是在HTML中嵌入动态内容:
sleep
...您当然可以将PHP代码嵌入到您想要的任何内容中; PHP解释器并不关心它。真正使文件成为PHP脚本的唯一原因是它已被提供给PHP解释器。
<p>Hello, <?=htmlspecialchars($name)?>!</p>
只是利用数据库来查找某些签名。如果您有一个常用的JPEG文件,可以用PHP块结束,那么它将被报告为图片。
总结一下: