如何使用PHP检测拉链炸弹?

如何使用PHP检测拉链炸弹?,php,zip,Php,Zip,我正在制作一个PHP脚本,使用ZipArchive对象检索用户给定的zip文件,解压并处理其中的文件。如何避免像这样的zip炸弹?查看zip\u条目\u文件大小: 它应该给出.zip文件中未压缩归档文件的实际大小。以下是手册页面上注释中提供的示例函数: function get_zip_originalsize($filename) { $size = 0; $resource = zip_open($filename); while ($dir_resource = z

我正在制作一个PHP脚本,使用
ZipArchive
对象检索用户给定的zip文件,解压并处理其中的文件。如何避免像这样的zip炸弹?

查看zip\u条目\u文件大小:

它应该给出.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";

在你接受上传的文件之前使用病毒扫描程序。难道你不能解压最上层吗?请告诉我我的答案是否有帮助,OP.@MatthewBlancarte:好的,有问题的压缩程序没有。@hakre:前提是病毒扫描程序本身不易受到压缩炸弹的攻击。这只是增加了复杂性,但没有真正解决问题。我用2.4M的零填充了
bomb
文件,将其压缩为
bomb.zip
文件(2.4K),复制了四次,然后将五个zip文件压缩为
文件.zip
(14K)。这个函数给了我一个12985字节的原始大小,这是五个zip文件的大小,而不是整个大小。事实上,我的PHP脚本不需要递归解压文件,所以事实上,如果用户提交一个zip炸弹,它会删除嵌套的zip档案,但是我对一个完整大小的解决方案很感兴趣。我自己也在研究这个问题,虽然上面的函数确实返回了我多次压缩的文件大小。在
42.zip的情况下,大小返回为
0
。我相信这是由于密码保护。而且这只检查顶层。对于ZIP中的ZIP,它需要是递归的。这个答案对于PHP8来说已经过时了。