将base64编码的用户数据放入img的src中是否安全



接受应该是base64编码图像数据的POST数据并将其用作imgsrc属性是否安全?

<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"的部分将被删除,从而损坏图像。

考虑到这一点,我制定了一个答案很好的解决方案:

  1. 我们知道base64图像的开头遵循类似于"data:image/png;base64"的模式,因此下面的代码可以捕获这个开头的

    $data = substr($imageBase64, 0, strpos($imageBase64, ",") + 1);
  2. 好吧,但我们只依赖于找到的第一个逗号,它不提供任何安全性。因此,让我们使用preg_replace()来确保我们捕获的字符串确实是我们所期望的。

    $data = preg_replace('#^data:image/[^;]+;base64,#', '', $data);
  3. 如果一切按计划进行,则存储在$data中的结果将是一个空字符串。否则,我们的图像在此不再有效。现在我们需要验证第一个逗号后面的内容,所以我们将简单地使用base64_decode。

    $img = preg_replace('#^data:image/[^;]+;base64,#', '', $imageBase64);
    if(base64_decode($img, true)) {
      // is valid
    } else {
      // not valid
    }
  4. 我们使用相同的preg_replace来替换字符串的开头,然后测试其余部分,看看它是否与有效的base64数据匹配。如果是正数,您可以将原始字符串存储在数据库中,而不用担心,因为它的字符串非常干净,如果是负数,我们将得到一个无效的图像。

最新更新