【问题标题】:PHP - What is the best method to check a file extension, as well as determine the true file type?PHP - 检查文件扩展名以及确定真实文件类型的最佳方法是什么?
【发布时间】:2014-01-16 06:02:56
【问题描述】:

我想知道$_FILES["file"]["type"]end(explode(".", $name)有什么区别,以及确定检索到的文件类型是否真的是文件的正确内容的适当方法。

例如,对名为“image.exe”并重命名为“image.jpg”的文件进行排序的最佳方法是什么。

我看过很多关于 MIME 类型的讨论,但似乎该方法已被弃用。

【问题讨论】:

    标签: php file types upload explode


    【解决方案1】:

    这是阅读扩展名的正确方法:

    $ext = pathinfo($name, PATHINFO_EXTENSION);
    

    检查某物是否为图像的正确方法是尝试使用图像工具读取它,例如imagemagickGD。 GD 更容易,但 imagemagick 更擅长处理大图像,例如从 12 兆像素相机上传的图像。

    如果您担心 jpg 真的是 exe,安全处理它的唯一方法是将其读取为 jpg 并尝试创建新的 jpg(通常同时调整其大小)。 Gmail 会处理图片附件。

    还要注意真正的 jpeg 可能存在某种漏洞,因此即使它是图像,将其传递给用户也是不安全的。您真的应该调整它的大小以创建一个新的“安全”jpeg,然后将其提供给用户。您可以根据需要制作一个相同大小的新 jpg,但将原始数据传递给其他用户是危险的。

    我什至不允许您网站的管理员用户访问随机互联网用户上传的 jpg。它可以用来入侵管理员的电脑。

    【讨论】:

    • 谢谢!我正在处理几种不同类型的图像 - 很可能是一些 .mp4 文件。
    • 基本上你必须找到可以读取你需要担心的每种类型文件的软件,并用它来检查文件是否有效。否则,您可以相信该用户不会尝试破解其他用户……这不是一个好主意。
    【解决方案2】:

    $_FILES["file"]["type"] 由用户的浏览器提供,因此对安全无用。

    如您所见,文件扩展名也很容易伪造。

    如果要确保图像是图像,最简单的方法是在其上运行getimagesize()

    如果您想确保超级并删除可能嵌入图像中的任何和所有元数据,请使用 GD 的 imagecreatefromstring() 将图像复制到空画布(但要为可能的轻微质量损失。)

    对于其他文件类型,现在显然有Fileinfo library。它使用底层操作系统的 mime.magic 文件通过检查文件中的某些特征和“标题字节”来估计文件的类型。

    【讨论】:

    • 您也可以只删除文件内容的前 60 个字符。 jpg 只有 3 个可能的值,gif 有 2 个,png 有 1 个。这就是 fileinfo 所做的一切,如果您担心安全性,那根本不安全。 gist.github.com/abhibeckert/8166418
    • @Abhi 那个检查器很好。重新安全-我假设您指的是您提到的漏洞利用-不过,我不确定这些是否只是理论上的可能性。目前在任何大众市场软件中是否存在任何已知的图像文件漏洞?毕竟,重新编码文件总是会降低质量。
    • "是否存在已知的图像文件漏洞?"是的,在过去几年中,Microsoft Windows 和 Internet Explorer 中已经出现了几十个。其他平台也已经倒下,尽管它往往是理论上的,而不是疯狂的利用。您说的对质量损失是正确的,没有好的解决方案。
    • @Abhi 我的意思是“已知且当前处于活动状态” - 这些东西可能会很快被插入(虽然,是的,未修复的 Windows 95 机器等)是的,这是一个权衡你的选择的问题 -如果您是摄影师社区,则可能必须提供原始图像。如果您是 Facebook,您希望将所有内容复制到空白画布上。
    • 没有任何已知的漏洞,没有。但这通常总是正确的。这取决于上传图片的人您对他们的信任程度。
    【解决方案3】:

    如果您只是处理图像文件,那么 getimagesize() 应该这样做: http://www.php.net/manual/en/function.getimagesize.php

    它将图像类型作为它返回的数组的元素返回,如果文件不是有效图像,则返回 FALSE。

    【讨论】:

      【解决方案4】:

      使用 end(explode(".", $name) 时要注意双重扩展。 如果给出了映射到相同元信息的 2 个扩展,Apache 将读取最右边的扩展。例如。 file.gif.html 将被关联为一个 html 文件。

      如上所述,客户端提供的浏览器信息作为安全措施是无用的。

      最佳选择 - getimagesize(); 与所有事情一样,有很多方法可以解决它。可以在图片中添加恶意代码注释,绕过getimagesize()检查,因为header仍然有效

      【讨论】:

      • 你在这里的最后一句话非常重要,应该突出显示。我会给你一个标记,但你说getimagesize()是最好的选择;虽然没关系;没有做任何事情来否定代码可以注入真正的 JPEG 等。
      猜你喜欢
      • 2010-10-03
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-06-03
      • 2016-02-04
      • 1970-01-01
      • 2013-08-19
      • 1970-01-01
      相关资源
      最近更新 更多