0

我正在尝试在我的应用程序中实现附件,并且用户能够上传图像文件(png、jpg、jpeg)。我已经阅读了关于图像上传的 OWASP 建议,其中一个提示是 - 将输入图像转换为位图(仅保留位图数据,并丢弃所有额外的注释),然后将位图转换为您想要的输出格式。一种合理的方法是先转换为 PBM 格式,然后再转换为 PNG。

图像保存为字节数组。

我正在尝试使用 ImageIO 库中的 ImageTranscoder 重写上传的图像。但我不确定它在做什么,以及是否从图像中删除了所有可能的恶意代码,因为似乎只有元数据被重写。

是否有任何建议,最佳实践,应如何实现预期目标以删除图像文件中所有可能的恶意代码?

4

1 回答 1

0

您不需要像 PBM 这样的中间文件格式,因为BufferedImage(这是在 Java 中表示内存位图的标准方式)只是普通的像素数据。您可以从编码的“任何东西”到解码的位图再到编码的 PNG。

你可以做你描述的最简单的方法是:

ImageIO.write(ImageIO.read(input), "PNG", output);

这是相当幼稚的代码,并且会破坏许多真实世界的文件,或者可能只是默默地不输出任何东西。您可能希望至少处理最正常的错误情况,如下所示:

BufferedImage image = ImageIO.read(input);
if (image == null) {
   // TODO: Handle image not read (decoded)
}
else if (!ImageIO.write(image, "PNG", output)) {
   // TODO: Handle image not written (could not be encoded as PNG)
}

其他需要考虑的事项:以上将删除元数据中的恶意代码。但是,可能会有针对 DoS 制作的特殊图像(小文件解码为巨大的内存表示、TIFF IFD 循环等等)。这些问题需要在各种输入格式的图像解码器中解决。但至少你的输出文件应该是安全的。

此外,恶意代码可能存储在 ICC 配置文件中,可能会转移到输出图像中。您可以通过强制将所有图像转换为内置 sRGB 色彩空间或写入没有 ICC 配置文件的图像来避免这种情况。


PS:该ImageTranscoder接口适用于您希望保留尽可能多的元数据的情况(这就是为什么它只有元数据的方法),并允许将元数据从一种文件格式转换为另一种文件格式(有人可能会争论名称应该是MetadataTranscoder)。

于 2020-09-04T08:01:13.537 回答