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

Java 将图像转换为固定格式以丢弃所有额外的注释,java,image,security,javax.imageio,transcode,Java,Image,Security,Javax.imageio,Transcode,我正在尝试在我的应用程序中实现附件,用户可以上传图像文件(png、jpg、jpeg)。我已经阅读了OWASP关于图像上传的建议,其中一个技巧是-将输入图像转换为位图(仅保留位图数据,并丢弃所有额外的注释),然后将位图转换为所需的输出格式。一种合理的方法是转换为PBM格式,然后转换为PNG 图像保存为字节数组 我正在尝试使用ImageIO库中的ImageTranscoder重写上传的图像。但我不确定它在做什么,也不确定是否从图像中删除了所有可能的恶意代码,因为似乎只有元数据在被重写 对于如何实现删

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

图像保存为字节数组

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


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

您不需要像PBM这样的中间文件格式,因为
buffereImage
(这是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
).

如果你指的是
javax.imageio.imageio
包,那么它是一个核心Java组件,应该没有恶意代码,并且应该进行优化。很抱歉,也许我的问题让人困惑。我试图使用imageIO库重写用户上传的输入文件(图像文件),图像中可能存在恶意代码,imageIO库是我想要用来重写上传文件的工具