Cli*_*ote 27 php upload file-upload image-processing mime-types
我想检查上传的文件是图像文件(例如png,jpg,jpeg,gif,bmp)还是其他文件.问题是我正在使用Uploadify上传文件,这些文件会更改mime类型并提供"text/octal"或类似mime类型的内容,无论您上传哪种文件类型.
除了使用PHP检查文件扩展名之外,有没有办法检查上传的文件是否是图像?
Ala*_*blo 39
我对这个主题的想法很简单:所有上传的图像都是邪恶的.
而且不仅因为它们可能包含恶意代码,而且特别是因为元标记.我知道浏览网页的抓取工具使用隐藏的元标记找到一些受保护的图像,然后播放他们的版权.也许有点偏执,但由于用户上传的图像不受版权问题的控制,我将其考虑在内.
为了摆脱这些问题,我使用gd系统地将所有上传的图像转换为png.这有很多优点:图像从最终的恶意代码和元标记清晰,我只有一种格式的所有上传的图像,我可以调整图像大小以符合我的标准,并... 我立即知道图像是否有效!如果无法打开图像进行转换(使用不关心图像格式的imagecreatefromstring),则认为图像无效.
一个简单的实现可能如下所示:
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);
}
Run Code Online (Sandbox Code Playgroud)
测试它:
header('Content-type: image/png');
imageUploaded('http://www.dogsdata.com/wp-content/uploads/2012/03/Companion-Yellow-dog.jpg', 'php://output');
Run Code Online (Sandbox Code Playgroud)
这并没有完全回答你的问题,因为这是与被接受的答案相同的黑客攻击,但我告诉你我使用它的理由,至少:-)
Sco*_*son 33
您可以使用getimagesize()哪个在非图像上返回零的大小.
如果Uploadify真的改变了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;
}
Run Code Online (Sandbox Code Playgroud)