14

在 php 中检查 mime 类型非常容易,但据我所知,mime 可以被欺骗。攻击者可以上传一个 php 脚本,例如 jpeg mime 类型。想到的一件事是检查上传文件的文件扩展名并确保它与 mime 类型匹配。所有这些都假设上传目录是浏览器可访问的。

问题:是否有任何其他技术可以防止“坏文件”进入 mime 类型的欺骗?

4

4 回答 4

13

简短的回答:没有。

更长的答案:

比较扩展名并确保它与 MIME 类型匹配并不能真正阻止任何事情。正如评论中所说,修改文件扩展名更加容易。MIME 类型和扩展名仅作为提示,它们没有内在的安全性。

确保传入的文件不会造成伤害在很大程度上取决于您对它们的目的是什么。在您的情况下,我了解您正在期待图像。所以你可以做的是首先执行一些完整性检查:扫描前几个字节以查看文件是否包含相关的图像头签名 - 所有相关的图像格式都有这些。

“签名标头”可帮助您确定文件尝试模拟的图像格式。在下一步中,您可以检查其余内容是否符合底层图像格式。这将保证您该文件确实是该特定格式的图像文件。

但即便如此,该文件也可以精心制作,当您显示图像时,用于显示该图像的流行库(例如 libpng 等)会遇到攻击者在该库中发现的缓冲区溢出。

不幸的是,除了根本不允许来自客户端的任何输入之外,没有办法主动阻止这种情况。

于 2011-11-06T16:25:17.867 回答
5

注意 - 这个答案现在已经过时了

getimagesize 的文档明确指出“不要使用 getimagesize() 来检查给定文件是否为有效图像。

如果是图像

  • 使用允许的列表检查扩展名(例如“.jpg”、“.jpeg”、“.png”)
  • 通过对文件运行getimagesize来检查上传的文件本身,如果它不是图像,它将返回 FALSE。

其他类型的上传

  • 检查允许的扩展名(例如“.pdf”)
  • 检查文件的 mime 类型是否与扩展名对应

示例代码:

function getRealMimeType($filename) {
    $finfo = new finfo(FILEINFO_MIME, "/usr/share/misc/magic"); 
    if (!$finfo) {
        echo "Opening fileinfo database failed";
        return "";
    }
    return $finfo->file($filename);
}

请参阅finfo_file文档。

于 2011-11-06T16:15:04.960 回答
-1

“mime_content_type”和“exif_imagetype”不应​​用于安全目的,因为它们都允许欺骗文件!

来自以下链接的更多详细信息: https ://straighttips.blogspot.com/2021/01/php-upload-spoofed-files.html

如果文件要上传到“public_html”文件夹中的某个位置,最好的方法是检查文件扩展名以阻止危险的文件扩展名,例如“.php”!

防病毒扫描可能是一个不错的选择,因为防病毒会检测到一些欺骗性文件!

于 2021-01-17T04:40:14.883 回答
-7

检查扩展名。

<?php

$okFiles = array('jpg', 'png', 'gif');

$pathInfo = pathinfo($filename);

if(in_array($pathInfo['extension'], $okFiles)) {
    //Upload
} 
else {
    //Error
}

?>

你也可以——就像你说的——检查扩展名是否匹配 MIME 类型,但是只检查扩展名要容易得多。

顺便说一句,你为什么关心 MIME 类型?

于 2011-11-06T16:12:31.023 回答