【错误记录】导入xlsx文件 解析文件内容时出错java.io.IOException: Zip bomb detected 错误原因及解释

导入文件时,报错信息:
在这里插入图片描述

事件起因:

在编写一个后端接口,导入文件的功能的时候,一旦导入一个excel文件 后端就会报这个错误,然后这个接口也就不能去具体执行相应的业务功能

在网络上看了许多的解决办法,但是很多都没有对其原因进行解释,在找完相关资料后来记录一下,这个bug的原因
希望在发现问题解决问题的过程中,能够做到:知其然,知其所以然

ZipBomb是什么?

首先要明白这是一个什么东西,直译就是 “压缩炸弹” 在导入文件时会对压缩文件进行识别,然后判断它的压缩率,至于为什么要去判断这个,大家可以去搜索一下这个ZipBomb是什么(最经典的就是一个42kb的压缩包其实是一个4.5Pb的炸弹,这会直接占满你的电脑磁盘空间)
1PB = 1024TB
1TB = 1024GB
1GB = 1024MB
1MB = 1024KB
1KB = 1024B

在写程序(后端接口上传文件时),检查拉链炸弹(即包含大量高度可压缩数据(00000000000000000 …)的zip文件) 是从安全的角度去考虑,避免上传的文件占满服务器的磁盘空间

关于压缩率的设置:
ZipSecureFile.setMinInflateRatio(-1.0d);

ZipSecureFile.setMinInflateRatio(0.009);

ZipSecureFile.setMinInflateRatio(0);

括号中的数字所代表的意思是:压缩率, 是compressBytes / uncompressBytes 的比率 也就是 “压缩后大小 / 压缩前大小” 如果这个比率是0.01d 说明压缩后文件比压缩前文件小100倍而没有信息丢失,换句话说,压缩文件仅在文件大小的1%中存储相同的信息 压缩率是一个分数,分子(压缩)必定小于或等于分母(未压缩)所以取值范围为 (0,1]
若不进行set设置压缩率,压缩率默认为 1% (= 0.01d),即当任何给定的读取包部分的压缩率优于(压缩效果更好,低于默认值) 1% 时,解析将失败,指示 Zip-Bomb。

明白了 ZipBomb 是什么后,有不少小伙伴就有了一个疑问:

疑问:我明明导入的是一个excel 都不是压缩文件 为什么会进行压缩炸弹的检测呢?

这个还得根据导入的文件类型来说:
我们常使用的excel文件其实有两种后缀名(两种文件类型),也就是".xls"和".xlsx"
这两种文件格式还是存在着细微区别的
xls:该文件格式是excel2007之前版本的默认格式
xlsx:xlsx是excel 2007之后的版本使用的默认格式,包括2007的版本,xlsx是用新的基于XML的压缩文件格式取代了xls默认文件格式

xlsx在本质上还是一个zip文件,将xlsx(或xlsm)文件扩展名改为zip,用解压软件解压,可以看到OOXMl格式的文件内容
将我的xlsx文件后缀名变为zip用解压软件打开的样子:
在这里插入图片描述

已测试导入xls文件和xlsx文件时(同一个文件导出格式分别为xls和xlsx两份) (从下图就可以看出这两种文件的有压缩和没有压缩在大小上的区别 )
在这里插入图片描述

调用接口测试两个文件的导入情况,报错信息不同:
xls文件:
在这里插入图片描述
xlsx文件的报错就是上面第一张图那样的

解决办法

办法就是在读取文件前设置压缩率为 -1.0d 这样的压缩率永远无法达到, 所以不会有比这个比率更优(低)的比率,这样其实相当于关闭了判断文件的压缩率,不过这样笔者觉得可能会引发安全问题,但我们平常的一些小系统开发,又不需要考虑这样的安全问题(又没有任何的商业价值,不会谁吃饱了撑的闲得没事真的来搞我的服务器吧!嘶嘶嘶~~ 搞不好真有,但不是我这种小开发该考虑的问题)
ZipSecureFile.setMinInflateRatio(-1.0d);

参考资料

ZipSecureFile类的说明:
https://poi.apache.org/apidocs/dev/org/apache/poi/openxml4j/util/ZipSecureFile.html

其他文章参考:
https://www.qedev.com/dev/151394.html

结束语

若是对你有所帮助的话,希望能获得你的 点赞、评论、收藏,这将是对我很大的鼓励!!! 这对我真的很重要!!!
蟹蟹٩(‘ω’)و

  • 16
    点赞
  • 29
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

阿,葱来了-C is coming

老板大气

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值