验证base64编码的图像

ssh*_*ksh 23 php security validation base64

我正在构建一个应用程序,允许用户使用POSTHTML5画布数据,然后在base64中编码并显示给所有用户.我正在考虑将数据解析为实际的.png文件并存储在服务器上,但base64路由允许我将图像存储在数据库中并最小化请求.图像是唯一的,很少,并且页面不会经常刷新.

一些jQuery将获取画布数据,data:image/png;base64,iVBORw...并将其传递给包含它的PHP脚本,如下所示:<img src="$data"></img>

但是,安全性是基础,需要验证base64画布数据以防止在POST请求中传递恶意数据.我主要关心的是防止外部URL被注入到<img>标记中并在页面加载时被请求.

我目前有这样的设置:

$data = (isset($_POST['canvas']) && is_string($_POST['canvas'])) ? $_POST['canvas'] : null;
$base = str_replace('data:image/png;base64,', '', $data);
$regx = '~^([A-Za-z0-9+/]{4})*([A-Za-z0-9+/]{4}|[A-Za-z0-9+/]{3}=|[A-Za-z0-9+/]{2}==)$~'

if ((substr($data, 0, 22)) !== 'data:image/png;base64,')
{
  // Obviously fake, doesn't contain the expected first 22 characters.
  return false;
}

if ((base64_encode(base64_decode($base64, true))) !== $base64)
{
  // Decoding and re-encoding the data fails, something is wrong
  return false;
}

if ((preg_match($regx, $base64)) !== 1) 
{
  // The data doesn't match the regular expression, discard
  return false;
}

return true;
Run Code Online (Sandbox Code Playgroud)

我想确保我当前的设置足够安全,以防止外部URL插入<img>标签,如果没有,可以做些什么来进一步验证图像数据?

the*_*guy 24

这样做的一种方法是实际从base64数据创建一个图像文件,然后用PHP验证图像本身.可能有一种更简单的方法,但这种方式肯定会起作用.

请记住,这只适用于PNG,如果您计划允许更多文件类型(GIF,JPG),则需要添加一些逻辑.

<?

$base64 = "[insert base64 code here]";
if (check_base64_image($base64)) {
    print 'Image!';
} else {
    print 'Not an image!';
}

function check_base64_image($base64) {
    $img = imagecreatefromstring(base64_decode($base64));
    if (!$img) {
        return false;
    }

    imagepng($img, 'tmp.png');
    $info = getimagesize('tmp.png');

    unlink('tmp.png');

    if ($info[0] > 0 && $info[1] > 0 && $info['mime']) {
        return true;
    }

    return false;
}

?>
Run Code Online (Sandbox Code Playgroud)

  • 我通过代码审查偶然发现了这个答案。请不要在生产环境中使用它,因为它非常不安全。您不应该*永远*对未知数据使用“imagecreate”函数之一,因为它会为整个图像分配位图缓冲区。创建 100+MP 的小 png 文件非常容易,这会毁了你的一天。相反,将图像写入临时文件并对其调用“getimagesize”。(此处注明注意事项:https://php.net/getimagesize)如果您必须分配图像,则只需使用“imagesx”和“imagesy”直接查询尺寸。 (3认同)

cur*_*y26 5

如果您使用的是PHP 5.4+,我已将上述内容修改为更简洁.

function check_base64_image($data, $valid_mime) {
    $img = imagecreatefromstring($data);

    if (!$img) {
        return false;
    }

    $size = getimagesizefromstring($data);

    if (!$size || $size[0] == 0 || $size[1] == 0 || !$size['mime']) {
        return false;
    }

    return true;
}
Run Code Online (Sandbox Code Playgroud)

  • 喜欢它.几个笔记... A)`$ valid_mime`argument似乎是多余的,B)这需要安装GD库 - 在Ubuntu上:`sudo apt-get install php5-gd && sudo service apache2 restart` (3认同)