记. ZIP炸弹防御问题
背景:
测试组搞了个“ZIP炸弹”传给后台,发现后台并没有识别,一度怀疑后台是不是偷懒了压根没有做安全校验。
于是,激动万分地给我提了个单。
排查:
阅读同事的代码,发现有做校验,步骤如下:
- 第一步,校验ZIP压缩包大小。
- 第二步,校验ZIP压缩包解压后的大小。
于是随便拿了个ZIP包本地验了一把,明明算得很准啊,一个字节都不差,是不是测试搞错了?!
再去测试组要了他们搞出来的变态ZIP包验了一把,发现校验得出的解压大小比实际小了许多。
问题:
显然,问题就出在第二步。
有个ZipUtil工具类,注释清一色地道英文,不知道原作者是哪位大神,也不知最初是谁从哪里拷过来的。
这个类提供的校验方法是通过传入ZIP文件的输入流,然后一顿字节操作猛如虎得出解压大小。计算过程涉及的变量和运算没有任何注释,看不懂啊——我摊牌了!
解决:
既然看不懂改不动,网上找替代方案吧。
很快,找到了一个方法改造一下:
/*** 计算ZIP文件的解压大小* * @param filePath 文件路径* @return 解压大小*/
public static long getUncompressedSize(String filePath) throws IOException {ZipFile zipFile = new ZipFile(filePath);long uncompressedSize = 0;Enumeration<? extends ZipEntry> entries = zipFile.entries();while (entries.hasMoreElements()) {uncompressedSize += entries.nextElement().getSize();}return uncompressedSize;
}
拿几个ZIP包验了验,发现有时候会抛异常:java.util.zip.ZipException: error in opening zip file,明明很正常的包啊,也查不出个原因,莫名其妙,无奈,再找找吧。。。
于是有了下面的方法:
/*** 计算ZIP文件的解压大小* * @param inputStream 输入流* 注:输入流由调用方负责关闭* @return 解压大小*/
public static long getUncompressedSize(InputStream inputStream) throws IOException {ZipInputStream zipInputStream = new ZipInputStream(inputStream);long uncompressedSize = 0;ZipEntry zipEntry;while ((zipEntry = zipInputStream.getNextEntry()) != null) {uncompressedSize += zipEntry.getSize();zipInputStream.closeEntry();}return uncompressedSize;
}
这回妥妥的,原来的异常不再出现了,不过还是有点小问题,因为压缩包内出现中文,导致新异常出现了:java.lang.IllegalArgumentException:MALFORMED at java.util.zip.ZipCoder.toString(ZipCoder.toString:58),好吧,还必须将编码改为GBK,再改:
/*** 计算ZIP文件的解压大小* * @param inputStream 输入流* 注:输入流由调用方负责关闭* @return 解压大小*/
public static long getUncompressedSize(InputStream inputStream) throws IOException {ZipInputStream zipInputStream = new ZipInputStream(inputStream, Charset.forName("GBK"));long uncompressedSize = 0;ZipEntry zipEntry;while ((zipEntry = zipInputStream.getNextEntry()) != null) {uncompressedSize += zipEntry.getSize();zipInputStream.closeEntry();}return uncompressedSize;
}
接着验。。。嗯?zipEntry.getSize()等于-1是什么情况?!脑壳痛,再改:
/*** 计算ZIP文件的解压大小* * @param inputStream 输入流* 注:输入流由调用方负责关闭* @return 解压大小*/
public static long getUncompressedSize(InputStream inputStream) throws IOException {ZipInputStream zipInputStream = new ZipInputStream(inputStream, Charset.forName("GBK"));long uncompressedSize = 0;ZipEntry zipEntry;while ((zipEntry = zipInputStream.getNextEntry()) != null) {long size = zipEntry.getSize();// ZipEntry的size可能为-1,表示未知if (size == -1) {ByteArrayOutputStream baos = new ByteArrayOutputStream();int bytes;while ((bytes = zipInputStream.read()) != -1) {baos.write(bytes);}uncompressedSize += baos.size();baos.close();} else {uncompressedSize += size;}zipInputStream.closeEntry();}return uncompressedSize;
}
这次可以了,可是这一个字节一个字节地读效率太慢了,绝对不能拿来主义,得再改:
/*** 计算ZIP文件的解压大小* * @param inputStream 输入流* 注:输入流由调用方负责关闭* @return 解压大小*/
public static long getUncompressedSize(InputStream inputStream) throws IOException {ZipInputStream zipInputStream = new ZipInputStream(inputStream, Charset.forName("GBK"));byte[] buffer = new byte[8*1024*1024];long uncompressedSize = 0;ZipEntry zipEntry;while ((zipEntry = zipInputStream.getNextEntry()) != null) {long size = zipEntry.getSize();// ZipEntry的size可能为-1,表示未知if (size == -1) {int len;while ((len = zipInputStream.read(buffer, 0, buffer.length)) != -1) {uncompressedSize += len;}} else {uncompressedSize += size;}zipInputStream.closeEntry();}return uncompressedSize;
}
OK,验证没问题, 合一把代码,走单。
记. ZIP炸弹防御问题相关推荐
- ZIP炸弹怎样反击扫描器?
本文讲的是ZIP炸弹怎样反击扫描器?,如果你曾经维护一个网站或管理过服务器,那么你会清楚,总会人会尝试攻击你.当我在13岁时首次托管我自己的linux服务器时,我每天阅读日志,并查看每天有多少尝试连接 ...
- 惊爆:当Python代码遇到zip解压炸弹,未做防护的你后悔莫及!
zip解压炸弹 在文章的开头,让我们先来介绍一下zip解压炸弹是个 什么妖怪! 解压炸弹是指解压缩后能够产生巨大的数据量的可疑压缩文件!默认设置是文件扫描中产生500MB以上解压数据的是"解 ...
- 数仓拉链表使用_如何用拉链炸弹捍卫您的网站
数仓拉链表使用 This article was originally published on Christian's blog and republished here with his perm ...
- ZBLG:非递归zipbomb炸弹,比例为28000000:1
分享一个有趣的工具 ZBLG:非递归zipbomb炸弹,比例为28000000:1 存储有价,数据无价,谨慎使用,请勿用于非法用途. 译文发表记录声明 版本:V1 「个站:北岸冷若冰霜」A bette ...
- 压缩炸弹(zipbomb)制作(附演示)
最近看到资料有说到ZIP炸弹,主要在存在上传功能且对上传文件有解压动作的地方,如果校验不严,可能导致压缩炸弹,导致消耗CPU导致宕机 1.生成ZIP炸弹: https://github.com/Cre ...
- 一个42KB的文件,解压完其实是个4.5PB的“炸弹”
你听说过 ZIP 炸弹吗? 一个很小很小的,几十 KB 的压缩过后的文件,解压以后有几百万 GB ,好像炸弹一样. 在继续介绍它之前,差评君想先问问各位都用过哪些压缩软件... WinRAR ? 或者 ...
- pb 数据窗口插入数据_46MB 变4.5PB 数据炸弹:新方法突破性压缩资料
电脑文件相当多,对于不少用户的电脑来说,经常需要将一些文件进行压缩,解决空间不足的问题,Zip 就是最多人使用的格式之一,不过它亦是一把双刃剑,David Fifield制作一个内含超大量垃圾数据的z ...
- [转]信息安全相关理论题(三)
21.静态分析是运行程序后进行调试? A. 对 B. 错 您的答案: 标准答案: B 22.安卓反编译后会出现$符号字节码表示是匿名内部类? A. 对 B. 错 您的答案: 标准答案: A 23.反编 ...
- [转]信息安全相关理论题(二)
27.在工程实施之前,验收方可以不给施工方弱电布线图纸,但施工结束后必须有图纸 A. 对 B. 错 您的答案: 标准答案: B 28.在OSI七层协议中,提供一种建立连接并有序传输数据的方法的层是 A ...
最新文章
- 飞书,成就组织和个人 让每一分努力都有意义!
- 谷歌翻译无法连接网络_Windows无法连接网络,这几招教你解决
- python怎么自动中文版_Python实现AI自动版贪吃蛇
- kaggle机器学习作业(房价预测)
- 生理周期,POJ(1006)
- 搞懂C语言指针,看这篇就够了!
- 项目建立数据库初始环境脚本文件的示例
- 如何使用1Password,Authy和Privacy.com外包您的在线安全性
- Docker镜像和容器常用命令
- 吉士丁与新潮传媒达成亿级战略合作,打造国产奶酪新势力
- 灵魂拷问,SQL 查询语句先执行 SELECT吗?
- mybatis一次可以执行多个sql语句
- 制图折断线_无锡春华教育AutoCAD家具制图/机械/工程制图
- mongodb可视化工具robo3T的安装和使用
- linux 的空命令:(冒号)
- 【English】20190430
- python鼠标键盘事件代码_Python鼠标键盘事件
- MATLAB三维画图函数使用总结
- Fig (无花果)任务流水线式 多线程框架使用
- 计算半圆弧长及半圆的面积。(3分)