检查安全图像上传
Check secure image upload
我想从浏览器上传图片到服务器window。
我正在使用此功能来处理图像 upload.Images 由 GD 库上传。
您对此代码有何看法?
我想知道还有没有办法上传恶意文件?
<?php
function imageUpload($name, $thumb = false, $max_size = 5242880, $height = null, $width = null, $T__height = 100, $T__width = 100)
{
if(!isset($_FILES[$name]))
{
return false;
}
$allowedTypes = array('image/gif', 'image/jpeg', 'image/png', 'image/wbmp');
$image = &$_FILES[$name];
if ($image['error'] == 0 && in_array($image['type'], $allowedTypes) && $image['size'] <= $max_size)
{
$in = '';
switch ($image['type'])
{
case 'image/gif':
$in = 'imagecreatefromgif';
break;
case 'image/jpeg':
$in = 'imagecreatefromjpeg';
break;
case 'image/png':
$in = 'imagecreatefrompng';
break;
case 'image/wbmp':
$in = 'imagecreatefromwbmp';
break;
}
if ($in == '')
{
return false;
}
$src = $in($image['tmp_name']);
$height = ($height == null || $height <= 0 ? imagesy($src) : $height);
$width = ($width == null || $width <= 0 ? imagesx($src) : $width);
$dst = imagecreatetruecolor($width, $height);
imagecopyresized($dst, $src, 0, 0, 0, 0, $width, $height, imagesx($src), imagesy($src));
$fileName = '';
do
{
$fileName = makeHash(mt_rand(0, mt_getrandmax()) . microtime(true), $image['tmp_name']);
}
while(file_exists('/image/' . $fileName . '.jpg') || ($thumb && file_exists('/thumb/' . $fileName . '.jpg')));
if ($fileName == '')
{
return false;
}
imagejpeg($dst, '/image/' . $fileName . '.jpg', 75);
if ($thumb)
{
$dst = imagecreatetruecolor($T__width, $T__height);
imagecopyresized($dst, $src, 0, 0, 0, 0, $T__width, $T__height, imagesx($src), imagesy($src));
imagejpeg($dst, '/thumb/' . $fileName . '.jpg', 75);
}
imagedestroy($src);
imagedestroy($dst);
return $fileName . '.jpg';
}
}
?>
首先,任何类型的安全机制都不应依赖 mimetypes,因为攻击者可以完全控制该字段(他们可以上传类型为 [=15 的 .php 文件=] 将通过这些检查)。然后,如果它们在文件名 %00
或 [=11=]
中包含一个空字节,那么就可以绕过向图像添加 .jpg 扩展名的条件,就像这样 evil.php[=12=].jpg
所以到时候文件到达磁盘后将变为 evil.php。在没有看到所有功能的情况下很难全面评估您的代码,因为根据它们所做的一切可能会产生漏洞。 (例如,不清楚它们的文件存储位置、调用它们的内容、加载它们的内容等)。
我想从浏览器上传图片到服务器window。
我正在使用此功能来处理图像 upload.Images 由 GD 库上传。
您对此代码有何看法?
我想知道还有没有办法上传恶意文件?
<?php
function imageUpload($name, $thumb = false, $max_size = 5242880, $height = null, $width = null, $T__height = 100, $T__width = 100)
{
if(!isset($_FILES[$name]))
{
return false;
}
$allowedTypes = array('image/gif', 'image/jpeg', 'image/png', 'image/wbmp');
$image = &$_FILES[$name];
if ($image['error'] == 0 && in_array($image['type'], $allowedTypes) && $image['size'] <= $max_size)
{
$in = '';
switch ($image['type'])
{
case 'image/gif':
$in = 'imagecreatefromgif';
break;
case 'image/jpeg':
$in = 'imagecreatefromjpeg';
break;
case 'image/png':
$in = 'imagecreatefrompng';
break;
case 'image/wbmp':
$in = 'imagecreatefromwbmp';
break;
}
if ($in == '')
{
return false;
}
$src = $in($image['tmp_name']);
$height = ($height == null || $height <= 0 ? imagesy($src) : $height);
$width = ($width == null || $width <= 0 ? imagesx($src) : $width);
$dst = imagecreatetruecolor($width, $height);
imagecopyresized($dst, $src, 0, 0, 0, 0, $width, $height, imagesx($src), imagesy($src));
$fileName = '';
do
{
$fileName = makeHash(mt_rand(0, mt_getrandmax()) . microtime(true), $image['tmp_name']);
}
while(file_exists('/image/' . $fileName . '.jpg') || ($thumb && file_exists('/thumb/' . $fileName . '.jpg')));
if ($fileName == '')
{
return false;
}
imagejpeg($dst, '/image/' . $fileName . '.jpg', 75);
if ($thumb)
{
$dst = imagecreatetruecolor($T__width, $T__height);
imagecopyresized($dst, $src, 0, 0, 0, 0, $T__width, $T__height, imagesx($src), imagesy($src));
imagejpeg($dst, '/thumb/' . $fileName . '.jpg', 75);
}
imagedestroy($src);
imagedestroy($dst);
return $fileName . '.jpg';
}
}
?>
首先,任何类型的安全机制都不应依赖 mimetypes,因为攻击者可以完全控制该字段(他们可以上传类型为 [=15 的 .php 文件=] 将通过这些检查)。然后,如果它们在文件名 %00
或 [=11=]
中包含一个空字节,那么就可以绕过向图像添加 .jpg 扩展名的条件,就像这样 evil.php[=12=].jpg
所以到时候文件到达磁盘后将变为 evil.php。在没有看到所有功能的情况下很难全面评估您的代码,因为根据它们所做的一切可能会产生漏洞。 (例如,不清楚它们的文件存储位置、调用它们的内容、加载它们的内容等)。