将图像转换为固定格式,以丢弃所有多余的注释

问题描述

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

图像保存为字节数组。

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

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

解决方法

您不需要像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,output)) {
   // TODO: Handle image not written (could not be encoded as PNG)
}

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

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


PS:ImageTranscoder界面用于需要保留尽可能多的元数据的情况(这就是为什么它仅具有元数据方法的原因),并允许进行转换元数据从一种文件格式转换为另一种文件格式(可能会争辩其名称应为MetadataTranscoder)。

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...