将图像转换为固定格式以丢弃所有额外的注解

a0zr77ik  于 2021-07-05  发布在  Java
关注(0)|答案(1)|浏览(281)

我试图在我的应用程序实现附件和用户能够上传图像文件(png,jpg,jpeg)。我已经阅读了owasp关于图像上传的建议,其中一个技巧是将输入图像转换为位图(只保留位图数据,并丢弃所有额外的注解),然后将位图转换为所需的输出格式。一个合理的方法是转换成pbm格式,然后转换成png格式。
图像保存为字节数组。
我试图重写上传的图像使用imageio库的imagetranscoder。但我不确定它在做什么,也不确定是否所有可能的恶意代码都已从映像中删除,因为似乎只有元数据正在被重写。
有什么建议,最佳实践,如何达到预期的目标,以消除所有可能的恶意代码内的图像文件?

lnlaulya

lnlaulya1#

您不需要像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配置文件的情况下写入图像来避免这种情况。
附言:是的 ImageTranscoder 接口的目的是在您希望保留尽可能多的元数据的情况下(这就是为什么它只有元数据的方法),并允许将元数据从一种文件格式转换为另一种文件格式(有人可能认为名称应该是 MetadataTranscoder ).

相关问题