【问题标题】:Securing files in PHP site保护 PHP 站点中的文件
【发布时间】:2011-07-10 12:44:36
【问题描述】:

我有一个网站,它接受用户上传的文件(图像、pdf、word 文档等),然后允许其他用户下载它们。

我意识到这会带来安全风险,因为恶意用户可以上传伪装成有用文件的脚本等。

我的问题是——检查使用 PHP(mime_content_type 或 finfo)上传的文件的 mime 类型并将文件设置为只读(不可执行)是否足够,或者我还必须存储上传的文件在 Web 根目录之外的目录中?我认为这将消除上传文件的大部分风险,但我不确定。在这种情况下,无法对上传的文件执行病毒扫描。

感谢您的意见。

【问题讨论】:

    标签: php security mime-types


    【解决方案1】:

    一种常见的做法是在文档根目录之外上传文件,通常使用随机文件名,然后将这些文件名映射到数据库中正确的项目/对象/帖子。如果需要额外的权限来访问文件,请确保在允许下载之前检查它们,当然只有经过身份验证的用户才能上传。

    Fileinfo finfo_ 可用于验证大多数 mimetypes,至少可以验证名为“.txt”的内容实际上是文本文件而不是二进制 blob,或者“.jpg”确实看起来是基于 jpeg 的在它的前几个或最后几个字节上。它可能需要一些额外的工作来整理 MS Office mimetypes,就好像我没记错一样,它们都以 application-msword 的形式出现。但是您可以使用文件扩展名来确定它真正应该是什么(xls、ppt、doc 等)。

    然后一个 PHP 脚本提供下载的文件,而不是直接提供它的 Web 服务器。出于这个原因,您应该将 mime 类型与其一起存储,以便您可以提供适当的标头。

    header("Content-type: application-whatever");
    header("Content-length: size-of-the-file-in-bytes");
    

    【讨论】:

    • 嗨迈克尔-感谢有关 finfo 的提示。我会调查的。此外,随机文件名是我已经实现但忘记提及的东西,所以应该很好。
    • 如果您还没有php.net/manual/en/ref.fileinfo.php,请在此处查看 Fileinfo 文档
    • 请注意,即使是内容嗅探也不能保护您免受多用途文件的侵害 - 例如。连接 GIF 图像+ZIP 存档(按此顺序)将为您提供一个既是有效的 GIF 文件又是有效的 ZIP 存档的文件(因为 GIF 在前面有标题,而 ZIP 在末尾)。
    【解决方案2】:

    我可以建议您使用所有可用的工具来测试文件类型。但要知道黑客可以通过其他方式植入危险文件。

    最好的办法是将文件上传到不同的服务器。一种只能托管文件。

    【讨论】:

    • 是的,我同意我自己的东西,我会使用 Amazon S3 或类似的东西来处理图像和文件,但在这种情况下这不是一个选项。当您必须处理用户提交的文件的上传和服务时,我正在寻找将风险降至最低的策略。
    【解决方案3】:

    我会检查文件的 mime 类型,但我不会依赖它。即使该文件是完整的.gif 并且在其id3 标记中包含一个php 注释,它也可以是executed with a local file include。更安全的方法是使用long blob 数据类型将文件存储在数据库中。然而,这种开销是垃圾。

    从安全性、可扩展性和性能的角度来看,最好的解决方案是使用像 CouchDB 这样的无 SQL 数据库。

    有几件事要记住,不要相信$_FILES[]。 $_FILES['type'] 可能是攻击者想要的任何东西,因此从安全角度检查它是没有意义的。而$_FILES['name'] 可能会有像../../../ 这样的讨厌的输入。最好将文件重命名为主键,然后将有关该文件的信息存储在关系数据库(如 mysql)中。

    【讨论】:

    • 感谢 rook 的提示 - 如上所述,文件被重命名为随机名称,并且文件名存储在数据库中,因此已经处理好了。在检查 mime 类型之前,我们还将文件移动到 tmp 目录,然后重命名、chmod 并将文件移动到永久存储位置。
    • @julio 很酷,所以你唯一担心的是 LFI 攻击。 (除非攻击者在没有 sql 注入的情况下无法知道这个随机文件名,也许这就是重点……)
    猜你喜欢
    • 1970-01-01
    • 2012-04-14
    • 2011-03-20
    • 2010-11-26
    • 2010-09-13
    • 2016-06-05
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多