如何使用 PHP 检测 zip 炸弹?
Posted
技术标签:
【中文标题】如何使用 PHP 检测 zip 炸弹?【英文标题】:How to detect a zip bomb using PHP? 【发布时间】:2012-11-07 22:31:58 【问题描述】:我正在制作一个 php 脚本,它使用 ZipArchive
对象检索用户给定的 zip 文件、解压缩并使用其中的文件做一些事情。如何避免像42.zip 这样的拉链炸弹?
【问题讨论】:
在您接受之前对上传的文件使用病毒扫描程序。 不能解压顶层吗? 如果我的回答有帮助,请告诉我,OP。 @MatthewBlancarte:好吧,有问题的 zip 没有。 @hakre:前提是病毒扫描程序本身不易受到 ZIP 炸弹的攻击。这只是增加了复杂程度,并没有真正解决问题。 【参考方案1】:查看 zip_entry_filesize:http://php.net/manual/en/function.zip-entry-filesize.php
它应该为您提供 .zip 文件中未压缩存档的实际大小。以下是手册页评论中提供的示例函数:
function get_zip_originalsize($filename)
$size = 0;
$resource = zip_open($filename);
while ($dir_resource = zip_read($resource))
$size += zip_entry_filesize($dir_resource);
zip_close($resource);
return $size;
$size = get_zip_originalsize('file.zip');
echo "original size: $size bytes\n";
【讨论】:
我用 2.4M 的零填充了一个bomb
文件,我将它压缩成一个 bomb.zip
文件(2.4K),我将它复制了四次,然后我将五个 zip 文件压缩到file.zip
(14K)。该函数给了我一个 12985 字节的原始大小,这是五个 zip 文件的大小,而不是整个大小。
其实我的 PHP 脚本不需要递归解压文件,所以其实用户提交一个 zip 炸弹就可以了,它会删除嵌套的 zip 档案,但我感兴趣的是解决方案拥有整个尺寸。
我自己一直在研究这个,虽然上面的函数确实返回了我多次压缩的文件的大小。对于42.zip
,大小返回为0
。我相信这是由于密码保护。
这也只检查顶层。对于 zip 中的 zip,它需要是递归的。
这个答案对于 PHP8 来说已经过时了。以上是关于如何使用 PHP 检测 zip 炸弹?的主要内容,如果未能解决你的问题,请参考以下文章