保护PHP站点中的文件

时间:2011-03-07 17:34:29

标签: php security mime-types

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

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

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

感谢您提供意见。

3 个答案:

答案 0 :(得分:1)

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

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

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

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

答案 1 :(得分:1)

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

从安全性,可伸缩性和perforce的角度来看,

最佳解决方案将使用像CouchDB这样的无数据库。

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

答案 2 :(得分:1)

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

您最好的办法是将文件上传到其他服务器。一个只能托管文件的人。