Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/image-processing/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Php 如何检查上传的文件是否是没有mime类型的图像?_Php_Image Processing_File Upload_Upload_Mime Types - Fatal编程技术网

Php 如何检查上传的文件是否是没有mime类型的图像?

Php 如何检查上传的文件是否是没有mime类型的图像?,php,image-processing,file-upload,upload,mime-types,Php,Image Processing,File Upload,Upload,Mime Types,我想检查上传的文件是图像文件(例如png、jpg、jpeg、gif、bmp)还是其他文件。问题是我使用Uploadify来上传文件,这会改变mime类型,并给出一个“text/octal”或类似的mime类型,无论上传的是哪种文件类型 除了使用PHP检查文件扩展名外,还有没有其他方法可以检查上传的文件是否为图像?您可以使用PHP检查非图像的大小,返回零。您可以检查文件的前几个字节以确定图像格式 您可以通过检查文件开头的幻数来验证图像类型 例如:每个JPEG文件都以一个“FF D8 FF E0”块

我想检查上传的文件是图像文件(例如png、jpg、jpeg、gif、bmp)还是其他文件。问题是我使用Uploadify来上传文件,这会改变mime类型,并给出一个“text/octal”或类似的mime类型,无论上传的是哪种文件类型


除了使用PHP检查文件扩展名外,还有没有其他方法可以检查上传的文件是否为图像?

您可以使用PHP检查非图像的大小,返回零。

您可以检查文件的前几个字节以确定图像格式

您可以通过检查文件开头的幻数来验证图像类型

例如:每个JPEG文件都以一个“FF D8 FF E0”块开始


以下是有关

尝试使用以检索图像的实际类型的详细信息。如果文件太小,它将抛出一个错误,如果它找不到它,它将返回false

我对这个主题的想法很简单:所有上传的图像都是邪恶的

这不仅是因为它们可能包含恶意代码,尤其是因为元标记。我知道有些爬虫会浏览网页,使用隐藏的元标记找到一些受保护的图像,然后利用它们的版权进行游戏。也许有点偏执,但由于用户上传的图片无法控制版权问题,我认真考虑了这一点

为了解决这些问题,我使用gd系统地将所有上传的图像转换为png。这有很多好处:图像是从最终的恶意代码和元标记清除,我只有一种格式的所有上传的图像,我可以调整图像大小,以符合我的标准,和我立即知道图像是否有效 一个简单的实现可以如下所示:

function imageUploaded($source, $target)
{
   // check for image size (see @DaveRandom's comment)
   $size = getimagesize($source);
   if ($size === false) {
      throw new Exception("{$source}: Invalid image.");
   }
   if ($size[0] > 2000 || $size[1] > 2000) {
      throw new Exception("{$source}: Too large.");
   }

   // loads it and convert it to png
   $sourceImg = @imagecreatefromstring(@file_get_contents($source));
   if ($sourceImg === false) {
      throw new Exception("{$source}: Invalid image.");
   }
   $width = imagesx($sourceImg);
   $height = imagesy($sourceImg);
   $targetImg = imagecreatetruecolor($width, $height);
   imagecopy($targetImg, $sourceImg, 0, 0, 0, 0, $width, $height);
   imagedestroy($sourceImg);
   imagepng($targetImg, $target);
   imagedestroy($targetImg);
}
要测试它,请执行以下操作:

header('Content-type: image/png');
imageUploaded('http://www.dogsdata.com/wp-content/uploads/2012/03/Companion-Yellow-dog.jpg', 'php://output');

这不完全回答你的问题,因为这是一种与接受的答案相同的黑客攻击,但是我给你我使用它的理由,至少:-(<)/p> < p>如果上传真的改变了MIME类型-我会认为它是一个bug。 这毫无意义,因为这会阻碍开发人员使用 PHP中基于mime类型的函数:

  • ()
  • ()
  • ()
这是一个小助手函数,它根据文件的前6个字节返回mime类型

/**
 * Returns the image mime-type based on the first 6 bytes of a file
 * It defaults to "application/octet-stream".
 * It returns false, if problem with file or empty file.
 *
 * @param string $file 
 * @return string Mime-Type
 */
function isImage($file)
{
    $fh = fopen($file,'rb');
    if ($fh) { 
        $bytes = fread($fh, 6); // read 6 bytes
        fclose($fh);            // close file

        if ($bytes === false) { // bytes there?
            return false;
        }

        // ok, bytes there, lets compare....

        if (substr($bytes,0,3) == "\xff\xd8\xff") { 
            return 'image/jpeg';
        }
        if ($bytes == "\x89PNG\x0d\x0a") { 
            return 'image/png';
        }
        if ($bytes == "GIF87a" or $bytes == "GIF89a") { 
            return 'image/gif';
        }

        return 'application/octet-stream';
    }
    return false;
}

不能用计算机查询文件吗

这个答案未经测试,但基于上传论坛


我还想指出的是,在我看来,finfo应该是这样的,即使Uploadify指定了错误的mime类型,它仍然可以工作。

据我所知,这实际上是完成这项工作的公认黑客。如果存在更好的方法,我会很感兴趣。文档说它返回一个包含7个元素的数组,我需要检查哪个元素是否是图像?0,1表示宽度和高度。如果不是图像,它似乎只返回false。我接受这一点,但我仍然想知道是否还有其他选择。
exif_imagetype()
显然要快得多。在我看来,这不安全,攻击者可以在第一个字节中“FF D8 FF E0”,然后添加一些可能被执行的php代码,PHP代码也可以通过使用JPG元数据部分注入到有效的JPG文件中。我完全同意@Alain Tiemblo“我使用gd系统地将所有上传的图像转换为png”。这是关于安全性的方法。事实上,我的一位同事指出,如果你允许动画GIF,这是行不通的。是的,我同意你的看法,但是。。。每个人都知道GIF可以被利用()。如果您需要支持GIF,则可能需要花费一些时间和精力来过滤/清理格式。直接对任意数据使用
imagecreatefromstring()
,也很危险,因为DoS样式的攻击仍然可能只使用少量请求来填充服务器内存。您应该首先使用公认答案中提到的
getimagesize()
,以确保图像格式可读且尺寸合理,而不是直接从任意数据字符串创建整个图像资源(每像素4个字节,一个RGBa位图)。
$finfo = finfo_open(FILEINFO_MIME_TYPE);
$mimetype = finfo_file($finfo, $filename); //should contain mime-type
finfo_close($finfo);