PHP中的错误MIME类型检测

时间:2016-02-10 14:38:46

标签: 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类型?

谢谢!

2 个答案:

答案 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块结束,那么它将被报告为图片。

总结一下:

  • 不要向PHP解释器提供用户上传的任何内容
  • 验证您有有效图片的一种方法是将其作为图片处理,并在成功时使用结果(例如调整大小或进行优化)