使用apache poi解析Excel加水印时报错Zip Bomb

文章讲述了在使用ApachePOI处理大量Excel文件时遇到的ZipBomb问题,当文件压缩比率过低时引发异常。解决方案是调整ZipSecureFile的最小膨胀比以确保文件安全并避免内存耗尽。
摘要由CSDN通过智能技术生成

问题描述:

使用apache poi包对存在的excel文件添加水印操作,当excel数据量小的时候没啥问题,数据量大了就会报错Zip Bomb,具体报错如下:

java.io.IOException: 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. 
Uncompressed size: 105682, Raw/compressed size: 651, ratio: 0.006160 
Limits: MIN_INFLATE_RATIO: 0.010000, Entry: xl/styles.xml 
org.apache.poi.openxml4j.util.ZipArchiveThresholdInputStream.checkThreshold(ZipArchiveThresholdInputStream.java:132)
org.apache.poi.openxml4j.util.ZipArchiveThresholdInputStream.read(ZipArchiveThresholdInputStream.java:82)
org.apache.poi.util.IOUtils.toByteArray(IOUtils.java:182)
org.apache.poi.util.IOUtils.toByteArray(IOUtils.java:149)
org.apache.poi.util.IOUtils.toByteArray(IOUtils.java:136) org.apache.poi.openxml4j.util.ZipArchiveFakeEntry.<init>(ZipArchiveFakeEntry.java:47)
org.apache.poi.openxml4j.util.ZipInputStreamZipEntrySource.<init>(ZipInputStreamZipEntrySource.java:53)
org.apache.poi.openxml4j.opc.ZipPackage.<init>(ZipPackage.java:106)
org.apache.poi.openxml4j.opc.OPCPackage.open(OPCPackage.java:307)
org.apache.poi.ooxml.util.PackageHelper.open(PackageHelper.java:47)
org.apache.poi.xssf.usermodel.XSSFWorkbook.<init>(XSSFWorkbook.java:309)

问题原因:

这个异常 java.io.IOException: Zip bomb detected! 是由 Apache POI 库抛出的,用于处理 Excel 文件(如 XLSX 格式)。Apache POI 有一个安全特性,用于检测和处理潜在的 "zip bomb" 攻击。Zip bomb 是一种恶意压缩文件,它可以在解压时产生异常大量的数据,从而耗尽系统资源。

xlsx在本质上还是一个zip文件,excel文件在压缩后的大小与解压后的大小之间的比率太低(只有 0.006160),低于 Apache POI 设定的最小比率限制(默认是 0.01,即 1%)。这触发了异常,因为 Apache POI 认为该文件不安全,会消耗大量内存有导致内存耗尽的风险。

解决方案:

首先你要确认你的excel文件是没问题的,安全的文件,然后你就可以手动调整压缩率,低于报错的这个比率即可。

关键代码:ZipSecureFile.setMinInflateRatio(0.005);

public static void main(String[] args) {  
        // 设置最小压缩比率,例如 0.005(即 0.5%)  
        ZipSecureFile.setMinInflateRatio(0.005);  
  
        try (FileInputStream fis = new FileInputStream(new File("path/to/your/file.xlsx")))         
        {  
            // 创建 Workbook 对象(这里使用 XSSFWorkbook 来处理 XLSX 文件)  
            Workbook workbook = new XSSFWorkbook(fis);  
  
            // 接下来你可以使用 workbook 对象来读取和处理 Excel 文件  
            // ...  
  
            // 关闭 workbook(在 try-with-resources 语句中会自动关闭)  
        } catch (IOException e) {  
            // 处理异常  
            e.printStackTrace();  
        }  
}  
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值