接受应该是base64编码图像数据的POST
数据并将其用作img
的src
属性是否安全?
<img src="data:image/png;base64,[data here]" />
显然,如果没有过滤,人们可以很容易地突破src
属性和img
标签,插入恶意的<script />
或其他标签,所以我的想法是
base64_decode($rawPostData)
检查它是否解码正常,然后
base64_encode($decodedData)
以将其放入CCD_ 8属性中。
这种方法是否存在任何漏洞(例如XSS,可能是缓冲区溢出?)?
背景
对于一个使用JavaScript(准确地说是使用"canvg")将第三方svg
转换为canvas
再转换为base64
编码数据的页面,我需要它。我需要将图像传递给服务器端脚本,以便使用该图像执行一些其他任务,同时向用户/客户端显示图像。
我会接受图像作为图像,然后base64_encode
。它省去了检查它是否按预期提交这一不必要的中间步骤,也不可能导致XSS。
如果您必须像在图像中那样验证base64,那么简单地检查它只包含base64字符就足够了,因为您只是将它嵌入到img标记中(并且在base64中不允许使用破坏标记的字符)。
使用内置功能:
if (base64_decode($mystring, true)) {
// is valid
} else {
// not valid
}
如果不验证数据的内容,这是不安全的。
示例:
$data= '"/><script>alert("hi");</script>';
print '<img src="data:image/png;base64,'.$data.'" />';
检查$data
是否只包含有效的base64字符非常简单。这些都不会打破你的标签。
编辑:
以下情况只会导致图像损坏:
$data= '"/><script>alert("hi");</script>';
$data64 = base64_encode($data);
print '<img src="data:image/png;base64,'.$data64.'" />';
主要的安全问题是不能将干净的XSS应用于此类数据。如果应用干净的XSS,字符串"data:image/png;base64"的部分将被删除,从而损坏图像。
考虑到这一点,我制定了一个答案很好的解决方案:
-
我们知道base64图像的开头遵循类似于"data:image/png;base64"的模式,因此下面的代码可以捕获这个开头的
$data = substr($imageBase64, 0, strpos($imageBase64, ",") + 1);
-
好吧,但我们只依赖于找到的第一个逗号,它不提供任何安全性。因此,让我们使用preg_replace()来确保我们捕获的字符串确实是我们所期望的。
$data = preg_replace('#^data:image/[^;]+;base64,#', '', $data);
-
如果一切按计划进行,则存储在
$data
中的结果将是一个空字符串。否则,我们的图像在此不再有效。现在我们需要验证第一个逗号后面的内容,所以我们将简单地使用base64_decode。$img = preg_replace('#^data:image/[^;]+;base64,#', '', $imageBase64);
if(base64_decode($img, true)) { // is valid } else { // not valid }
-
我们使用相同的preg_replace来替换字符串的开头,然后测试其余部分,看看它是否与有效的base64数据匹配。如果是正数,您可以将原始字符串存储在数据库中,而不用担心,因为它的字符串非常干净,如果是负数,我们将得到一个无效的图像。