使用 Apache POI - 检测到 Zip Bomb

Using Apache POI - Zip Bomb detected

当我尝试将数据写入 Excel sheet,使用包含超过 64000 条记录的 Apache POI,其中使用了 SXSSF,我收到以下错误:

Zip bomb detected! The file would exceed the max. ratio of compressed file size to the size of the expanded data. This may indicate that the file is used to inflate memory usage and thus could pose a security risk. You can adjust this limit via ZipSecureFile.setMinInflateRatio() if you need to work with files which exceed this limit. Counter: 820224, cis.counter: 8192, ratio: 0.009987515605493134Limits: MIN_INFLATE_RATIO: 0.01

我通过添加 ZipSecureFile.setMinInflateRatio(0.009) 找到了一个解决方案,但为什么会发生这种情况,我需要为上述错误提供的限制是多少?我应该在哪里添加解决方案?

解法参考:How can I determine if a Zip Bomb error thrown when retrieving an Excel files Styles Table is legitimate?

是否有其他解决方案?

"Zip bomb" 是一个用于攻击向量的术语,其中一个小的 zip 文件扩展为一个非常大的未压缩文件,因此可能导致耗尽内存或磁盘 space 等问题。

通常创建此类 zip 的目的是对从外部源接收 zip 文件的系统造成拒绝服务攻击。

由于 .xlsx 文件实际上是包含 XML 文件的压缩文件,因此有可能在 POI 中导致此类 zip 炸弹漏洞。

为了防止这种情况发生,Apache POI 内置并默认启用了一些安全措施。因此,如果您创建一个包含异常内容的文件,例如许多 rows/columns 具有相同的内容,您可以 运行 进入这些保护措施并收到如上所示的异常。

如果您完全控制已处理文件的创建,您可以调整错误消息中给出的设置以避免异常。

有关类似讨论,请参阅 https://bz.apache.org/bugzilla/show_bug.cgi?id=58499 for the related issue and ZIp-bomb exception while writing a large formatted Excel (.xlsx) and How to determine if a Zip Bomb error thrown when retrieving an Excel files Styles Table is legitimate?

您可以避免从 InputStream 读取而不是像这样从文件读取的 zip 炸弹问题

File fp = new File(excelFile);
FileInputStream fpis = new FileInputStream(fp);
try {
    wb = WorkbookFactory.create(fpis);
} finally {
    fpis.close();
}

但请注意 WorkbookFactory.create(java.io.InputStream) 处的文档说 "loading from an InputStream requires more memory than loading from a File"

解决方法是在打开工作簿之前添加这一行:

ZipSecureFile.setMinInflateRatio(0);