我刚看过拉链炸弹,即包含大量高度可压缩数据(00000000000000000 ...)的zip文件。

打开时,它们会填满服务器的磁盘。

在解压缩之前,如何检测zip文件是拉链炸弹?

更新你能告诉我在Python或Java中是如何完成的?

压缩率可以像1000比1那样 - 不仅耗费大量磁盘空间,而且还需要很长时间来写入输出。

关于gzip和bzip2的相关问题。

在Python中试试这个:

import zipfile
z = zipfile.ZipFile('c:/a_zip_file')
print 'total files size=', sum(e.file_size for e in z.infolist())
z.close()

至少使用gzip我认为未压缩的大小可能不在标题中(因此它可能适用于zip,但不适用于.tar.gz)

@tonfa,谢谢你提到zipfile不能处理gnu zip格式。

IIRC,Zip标准(让我们面对它,如果你想引起DoS,你必须遵循标准)允许从中央目录和条目标题中省略某些大小。

最着名的拉链炸弹将通过这个测试,因为第一级不是很大。您还需要检查ZIP深度(ZIP内的ZIP)。

@ZZ Coder,嗯,这是真的。 Tom Hawtin - 如果你一次解压缩所有级别,那么tackline的解决方案会更好。

标题是"防篡改"吗?

@Kevin,你问解压缩程序是否确实验证了"大小"属性?好点子。如果没有,那么上面的代码当然可以"失败"。

这在多层拉链炸弹上根本不起作用

是否有可用的Java API或代码?

@ SAN3查看docs.oracle.com/javase/7/docs/api/java/util/zip/…

如果你在普通拉链中加入拉链炸弹怎么办?

@ZZCoder当你不递归地解压缩ZIP文件时(意味着解压缩初始ZIP的内部ZIP文件)你不受多层拉链炸弹的影响,是吗?我真的可以想象为什么有人想要递归地解压缩,但我想会有一些用例......

Zip是一种"有趣"的格式。一个强大的解决方案是将数据流出,并在您有足够的时间后停止。在Java中,使用ZipInputStream而不是ZipFile。后者还要求您将数据存储在临时文件中,这也不是最好的想法。

阅读维基百科上的描述 -

拒绝任何包含压缩文件的压缩文件。

    使用ZipFile.entries()检索文件列表,然后使用ZipEntry.getName()查找文件扩展名。

拒绝包含超过设定大小的文件的任何压缩文件,或者无法在启动时确定大小。

    迭代文件时,使用ZipEntry.getSize()来检索文件大小。

不允许上传过程写入足够的数据来填满磁盘,即解决问题,而不仅仅是问题的一个可能原因。

首先检查一个zip标题:)

查看Nick Dandoulakis的回答中的评论

如果您使用的ZIP解压缩程序可以提供原始和压缩大小的数据,则可以使用该数据。否则开始解压缩并监视输出大小 - 如果它增长太多则将其松散。

确保您没有使用系统驱动器进行临时存储。我不确定如果遇到它,病毒扫描仪是否会检查它。

您还可以查看zip文件中的信息并检索内容列表。如何执行此操作取决于用于提取文件的实用程序,因此您需要在此处提供更多信息