首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >验证base64编码的图像

验证base64编码的图像
EN

Stack Overflow用户
提问于 2012-09-30 12:31:48
回答 8查看 32.5K关注 0票数 27

我正在构建一个应用程序,它允许用户对HTML5画布数据进行POST,然后将这些数据编码成base64并显示给所有用户。我正在考虑将数据解析成实际的.png文件并存储在服务器上,但是base64路由允许我将图像存储在数据库中,并最大限度地减少请求。图像是独一无二的,很少,页面不会经常刷新。

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

但是,安全性是基石,需要验证base64 canvas数据以防止在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;

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

EN

回答 8

Stack Overflow用户

回答已采纳

发布于 2012-09-30 12:55:07

要做到这一点,一种方法是从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;
}

?>
票数 31
EN

Stack Overflow用户

发布于 2017-01-04 23:52:20

如果你使用的是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;
}
票数 5
EN

Stack Overflow用户

发布于 2014-07-18 18:29:01

function RetrieveExtension($data){
    $imageContents = base64_decode($data);

    // If its not base64 end processing and return false
    if ($imageContents === false) {
        return false;
    }

    $validExtensions = ['png', 'jpeg', 'jpg', 'gif'];

    $tempFile = tmpfile();

    fwrite($tempFile, $imageContents);

    $contentType = finfo_file(finfo_open(FILEINFO_MIME_TYPE), $tempFile);

    fclose($tempFile);

    if (substr($contentType, 0, 5) !== 'image') {
        return false;
    }

    $extension = ltrim($contentType, 'image/');

    if (!in_array(strtolower($extension), $validExtensions)) {
        return false;
    }

    return $extension;
}
票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/12658661

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档