3

我知道(从这个问题的答案:.rar, .zip files MIME Type)大多数人在 PHP 中检查 zip 文件为application/zipor application/octet-stream,但我对此有几个问题:

  • 检查是否安全application/octet-stream(因为它application/octet-stream可以用来描述更多的文件类型,而不仅仅是 zip!)。我知道我也可以用其他方式检查文件,但我认为我应该尽量让一切都尽可能简单
  • 我尝试尽可能多地检查不同的实际拉链类型;但是,有些会产生一些意想不到的结果。我发现 1 的 mime-type 是application/x-external-editor,但是 PHP 在处理它时遇到了问题(尽管我得到的唯一错误是Warning: ZipArchive::close() [ziparchive.close]: Invalid or unitialized Zip object) - 这在任何地方都有记录吗?是否有x-PHP 可以处理的实际 mimetype 列表?

编辑

回答以下问题:

  • 我通过 using 检查 mime 类型$_FILES['fileatt']['type'],但 usingmime_content_type()给出了相同的结果。不同的 zip 文件似乎是以下任何一种:'application/zip', 'application/x-compressed', 'application/x-zip-compressed', 'application/x-compressed', 'multipart/x-zip'. 我不明白为什么当 mime 类型被检测为application/x-external-editor.
  • 我已经安装了 zip 扩展程序,并且在上传 zip 文件时,我正在从 zip 文件中提取所有文件。我没想过检查错误。

我还发现了另一件事我不太明白:当我将以下代码与 PHP 读取为的文件一起使用时application/x-external-editor

if($zip->open($_FILES[fileatt]['tmp_name'])===TRUE)
{
    echo "success";
} else {
    echo "error";
} 

打印“错误”,但检查文件类型为

$res = $zip->open($_FILES[fileatt]['tmp_name']);
if($res)
{
    echo "success";
} else {
    echo "error";
} 

打印“成功”;在这段代码中,我假设布尔值有效地使用==, not ===,但是为什么这会有所作为呢?

错误:

$res = $zip->open($_FILES[fileatt]['tmp_name']);
if($res===TRUE)
{
    echo "success";
} else {
    echo $res;
} 

打印- 19 指的是19哪个错误(http://uk3.php.net/manual/en/ziparchive.open.php )?!

4

1 回答 1

3

永远不要相信 mime 类型,这很容易被客户端欺骗。如果他们愿意,他们可以提交一个 exe 并给它一个 mime 类型text/plain

所有 zip 文件都以标准的本地文件头签名 (0x04034b50) 开头,因此您可以检查文件的前 4 个字节是否与 zip 签名字节匹配。有关详细信息,请参阅PKZIP Appnote

如果您启用了zip 扩展,您可以更进一步,尝试打开并读取 zip 以确保它是完全有效的 zip 文件。

像这样的东西效果很好:

$zip = zip_open('/path/to/file.zip');
if (is_int($zip)) {
    echo "Error $zip encountered reading the file, is it a valid zip?";
} else {
    echo "Thanks for uploading a valid zip file!";
}

zip_open如果成功打开,则返回一个资源,否则返回一个整数,表示读取文件时发生的错误。

编辑:详细说明您的一些问题:

About application/octet-stream:正如你所说,这是一个非常通用的类型。这只是意味着任何包含 8 位数据的文件,基本上是所有内容。 application/zip是事实上的标准 mime 类型,但某些客户端会使用您发现的其他值。还考虑到客户端可以轻松欺骗任何文件类型以使用application/zip我不会依赖的事实,$_FILES['fileatt']['type']因为它可以是任何东西。

AFIK,mime_content_type()只需查看文件扩展名并将其映射到系统上的mime.types文件或内置于 PHP 中的 mime 类型。如果有人.zip在文件上添加扩展名,exe它仍然会注册为application/zip. 我相信某些扩展可能会检查文件头。

Zip::open()TRUE如果文件打开成功,则返回一个整数错误代码。因此,==会给你一个错误的误报,因为任何非零整数都将评估为真,==因为它会将非零整数转换为TRUE. 如果您要检查Zip::open您的回报,应始终使用$res === true以检查是否成功。您可以在页面底部的评论中找到错误代码含义。

底线:由于您说您已经在提取 zip,因此根据 mime 类型进行验证可能不会那么麻烦,但是尝试打开文件并根据open. 如果它返回 true,您可以确定该文件是一个有效的 zip(当然,文件后面可能会出现错误,但他们至少上传了类似于 zip 文件的内容)。

希望对您有所帮助。

于 2012-05-11T20:43:01.103 回答