我正在使用这个函数调用,因为当我读取一个受信任的文件时,它会导致 zipbomb 错误。
ZipSecureFile.setMinInflateRatio(double ratio)
FileInputStream file = new FileInputStream("/file/path/report.xlsx");
ZipSecureFile.setMinInflateRatio(-1.0d);
XSSFWorkbook wb = new XSSFWorkbook(file);
我想了解它是如何工作的?
我能找到的唯一来源是 https://poi.apache.org/apidocs/org/apache/poi/openxml4j/util/ZipSecureFile.html
但是,由于我对这个概念不熟悉,因此无法获得清晰的画面。
之间有什么区别
ZipSecureFile.setMinInflateRatio(-1.0d);
对比
ZipSecureFile.setMinInflateRatio(0.009);
对比
ZipSecureFile.setMinInflateRatio(0);
最佳答案
zip 炸弹检测的工作方式如下:
在解压缩时,它会检查 compressedBytes/uncompressedBytes
比率,如果该比率低于特定值 ( MinInflateRatio
),则检测到炸弹。
因此,如果比值 compressedBytes/uncompressedBytes
是 0.01d
,那么这意味着压缩文件比未压缩文件小 100 倍,没有信息丢失。换句话说,压缩文件仅以文件大小的 1% 存储相同的信息,这是未压缩文件所需要的。使用现实生活数据,这真的不太可能。
为了说明这是多么不可能,我们可以(以一种流行的科学方式)看看压缩是如何工作的:
让我们把字符串"This is a test for compressing having long count of characters which always occurs the same sequence."
这需要 101 个字节。假设这个字符串在文件中出现了 100,000 次。然后解压缩它需要 10,100,000 字节。压缩算法会为该字符串提供一个 ID,并且只会存储该字符串一次,将其映射到该 ID,并且会存储 100,000 倍于该字符串在文件中出现的 ID。这将需要 101 个字节 + 1 个字节 (ID) + 100,000 个字节 (ID) = 100,102 个字节。例如,这将具有 compressedBytes/uncompressedBytes
的比率 0.009911089d
。
因此,如果我们将 MinInflateRatio
设置为低于 0.01d
,那么我们接受这种不太可能的数据压缩率。
我们还可以看到,如果 compressedBytes/uncompressedBytes
为 0,那么比率 0
只能是 compressedBytes
。但这意味着没有要解压缩的字节。所以 MinInflateRatio
的 0.0d
永远无法达到或低于。因此,使用 MinInflateRatio
的 0.0d
将接受所有可能的比率。
当然,MinInflateRatio
的 -1.0d
也永远无法达到或低于。因此,使用它也将接受所有可能的比率。