PHP验证base64编码的图片

4
我需要找到一种在PHP中验证base64编码图像的方法。
通过验证,我考虑XSS和其他类似的安全问题。
流程如下:
用户有一些参数,其中一个或多个是图像的base64编码字符串,并将它们发布到我的网站。 当我收到参数fx(例如img1),其值为base64编码的图像字符串时。
然后,我想确保这个base64编码字符串只包含图像,没有任何标签和黑客会尝试使用的其他任何东西。
有人知道任何可以帮助我的PHP函数或插件吗?

4
图片的内容并不重要,重要的是你如何使用它。如果你将本应作为图片处理的东西仅仅当作图片来处理,那么就不会有人可以注入HTML标签。因为你为什么要将一张图片视为HTML呢?因此,我们需要更多的上下文来正确回答这个问题。 - deceze
我只会将base64编码的字符串放入图像标签中。但是在我正在构建的系统中,安全性非常重要,所以我需要确保像XSS这样的东西不能在base64编码的图像中使用 :) - Anders Gerner
你的数据源是什么,为什么一开始就进行了 base64 编码?你是如何输出它的,作为 src="data:image/jpeg;base64,,还是解码后将数据保存为实际图像? - Markus AO
5个回答

9

您可以使用以下代码验证文件类型:

$file = 'Your base64 file string';
$file_data = base64_decode($file);
$f = finfo_open();
$mime_type = finfo_buffer($f, $file_data, FILEINFO_MIME_TYPE);
$file_type = explode('/', $mime_type)[0];
$extension = explode('/', $mime_type)[1];

echo $mime_type; // will output mimetype, f.ex. image/jpeg
echo $file_type; // will output file type, f.ex. image
echo $extension; // will output extension, f.ex. jpeg

$acceptable_mimetypes = [
    'application/pdf',
    'image/jpeg',
];

// you can write any validator below, you can check a full mime type or just an extension or file type
if (!in_array($mime_type, $acceptable_mimetypes)) {
    throw new \Exception('File mime type not acceptable');
}

// or example of checking just a type
if ($file_type !== 'image') {
    throw new \Exception('File is not an image');
}

$mime_type下,您将获得类似于application/pdfimage/jpeg的内容。
$file_type下,您将获得文件类型,例如图像。
$extension下,您将获得一个扩展名。
使用finfo_buffer,您可以使用一些预定义常量(链接),这可能会给您更多的信息。
通过这些信息,您可以简单验证它是图像、PDF还是您想要检查的任何其他内容。您可以在此页面中检查所有可用的MIME类型。
手册 PHP: finfo_open PHP: finfo_buffer PHP: finfo_buffer - 预定义常量 base64_decode MIME类型(IANA媒体类型)

4

你可以尝试使用imagecreatefromstring函数从字符串创建图像。

接下来,您可以测试图像的尺寸/类型。

如果您想再进一步,可以创建一个新的图像,然后尝试将用户图像复制到其中,并将其用作最终图像。由于最终图像最初是由您创建的,因此任何黑客都很难通过。


0

0
我只会将base64编码的字符串放入图像标签中。但是在我正在构建的系统中,安全性非常重要,所以我需要确保像XSS这样的东西不能在base64编码的图像中使用 :)
然后,您可以像处理其他用户输入一样进行操作:在将其放入HTML之前,对用户提供的文本进行htmlspecialchars编码,以保持HTML的完整性。Base64图像字符串也不例外。请参见The Great Escapism (Or: What You Need To Know To Work With Text Within Text)
当然,图像数据块可能会通过易受攻击的图像解析器打开您的完全不同的攻击向量。因此,您可能需要先将该图像字符串解码为图像资源,然后再使用gd或Imagick函数保存它,即打开并重新保存/重新编码图像。

0
$str = 'your  base64 code' ;

if (base64_encode(base64_decode($str, true)) === $str && imagecreatefromstring(base64_decode($img))) {
echo 'Success! The String entered match base64_decode and is Image';
}

这个答案缺少教育性的解释。 - mickmackusa

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接