上传中MIMEType的可靠性(PHP)

上传中MIMEType的可靠性(PHP),php,security,file-upload,mime-types,mime,Php,Security,File Upload,Mime Types,Mime,我有一个问题问了一段时间:文件的mime类型到底是如何确定的?我相信这是通过检查文件的特定字节是否包含任何已知的/,对吗 如果是这样,这就提出了另一个问题,假设我将一个带有伪GIF文件签名的bash脚本上传到一个只允许上传图像的网站,会发生什么?要么: mimetype检测例程足够智能,可以检测假签名,或者 image/gif错误地返回为mimetype,允许继续上载 我没有安装十六进制编辑器,我不喜欢从测试中得出与安全相关的结论,因为我可能会遗漏(或误解)某些内容,所以我的问题是:上面哪一个选

我有一个问题问了一段时间:文件的mime类型到底是如何确定的?我相信这是通过检查文件的特定字节是否包含任何已知的/,对吗

如果是这样,这就提出了另一个问题,假设我将一个带有伪GIF文件签名的bash脚本上传到一个只允许上传图像的网站,会发生什么?要么:

  • mimetype检测例程足够智能,可以检测假签名,或者
  • image/gif
    错误地返回为mimetype,允许继续上载
  • 我没有安装十六进制编辑器,我不喜欢从测试中得出与安全相关的结论,因为我可能会遗漏(或误解)某些内容,所以我的问题是:上面哪一个选项是正确的

    此外,是否有其他最佳实践(除了检查mimetype)来确保任何给定的文件实际上是它看起来/需要(或允许)的文件?提前谢谢


    PS:我只是想说清楚,我不是在问
    $\u文件中的
    类型
    索引。

    我的理解是,这(易受攻击的MIME类型)是文件名上传时应该通过各种方式加密,然后存储在数据库中,通过ID号检索的原因。基本上,如果有人试图上传恶意脚本,他们将永远无法找到它来运行它?

    我的理解是,文件上传代码中的MIME确定例程非常粗糙,$\u文件数组中的MIME类型根本不可信。根据我的经验,它很容易被欺骗

    您最好使用Fileinfo库,它提供了更健壮的文件类型检测


    如果您谈论的是
    $\u文件['userfile']['type']
    ,则此信息由浏览器发送。它可能存在也可能不存在,即使它存在,您也应该像对待任何其他用户输入一样对待它

    如果您对检查图像感兴趣,可以使用getimagesize函数来确定文件类型。对于无法理解的图像,此函数返回NULL。即使它返回有效的图像类型,您仍然可以拒绝该文件,例如,如果您希望使用GIF和JPEG,而您得到的是TIFF


    此外,Web服务器将决定是否执行的文件不取决于文件权限(执行位和shebang行)和文件扩展名。如果你检查一下这两个,你可能就没事了。

    文件中的
    类型
    索引来自浏览器/用户,它根本不可信。我使用的是Fileinfo(或类似文件),但问题仍然存在:如果mime是伪造的,Fileinfo是否足够聪明来检测它?据我从文档中了解,Fileinfo查看了头,并进行了一些试探来检测文件类型,而不需要(或依赖于)由浏览器发送的信息。PHP手册中关于fileinfo的页面说文件检测不是100%可靠。我想你可以设计一个可以愚弄它的文件。@GordonM:你知道有什么方法比Fileinfo更可靠吗?我想你可以执行一个外部实用程序,比如*ix file。我认为file实用程序的工作方式与fileinfo相同,它在文件中查找魔法字节。我怀疑没有100%可靠的方法来确定文件类型。毕竟,您可以将PHP脚本附加到GIF文件上,但在图像查看器中,它仍然看起来像GIF文件。与其试图找到一种方法来保证文件类型,不如找到一种方法对上传的文件进行沙箱处理并限制它们的功能,例如关闭它们上传到的目录的PHP引擎,但存储在数据库或CDN上并不总是一种选择。隐藏文件名不能被认为是安全的,并且可能会丢失有价值的语义数据(文件名本身)。我知道架构选项和注意事项,但我的问题主要是针对mime类型(错误?)检测和可能的替代方案。