2009-11-02 99 views
1

我使用PHP语言进行文件上传,并想知道我使用的以下方法是否安全?这个文件上传方法是否通过PHP安全?

我使用简单的方法进行文件上传, 我从$ _FILES检查文件名[“userfile的”] [“型”] ,然后,如果它有一个允许的文件扩展名,我上传的文件与一些随机数。 如果它是abc.zip,它可能会变成8w43x9d.zip。

请告诉我:这是一个非常糟糕的文件上传方法吗?

回答

2

随机生成的安全文件名肯定是件好事。但是,如果您允许文件扩展名通过webroot,您仍然需要确保扩展名不会在服务器上造成任何问题,例如.php(好的,应该在Web服务器中禁用PHP处理上传目录,但仍然)。如果您位于Windows服务器上,也会出现问题,即尾随点和空格会混淆文件系统;请确保您将扩展程序锁定为一些“已知正确”值。

不幸的是,['type']财产根本不能被依赖。有些浏览器不会填充内容类型,有些浏览器会放错类型,因为它们的操作系统设置很糟糕(一个臭名昭着的无用的IE浏览器默认调用JPEG image/pjpeg),有些浏览器总是会说application/octet-stream甚至text/plain

即使是['name']属性也是不可靠的;除了说谎或模糊值的浏览器之外,给定类型在特定机器上总会有意想不到的文件扩展名。或者,对于Mac和Linux客户端,完全有可能上传的文件根本没有扩展名(或者甚至可能对操作系统认为的类型有错误的扩展名)。

所以是的,这一切都是一团糟。虽然从Content-Type提交或文件扩展名中嗅探类型可能对猜测文件的默认类型有用,但它完全不可靠,因此提供手动方法来选择文件类型是一件好事。或者,如果您将上传的文件作为附件提供服务(例如,通过PHP脚本设置Content-Disposition: attachment),则通常只需调用application/octet-stream即可让用户在保存时将其排除。

如果您不作为附件提供服务,则可能存在安全问题。 IE会高兴地嗅探你为<html>标签提供服务的许多文件类型,并将这些文件视为HTML,即使你告诉它它们是别的东西。然后它可以在浏览器中以内联方式显示它们,并让它们将脚本注入安全上下文中。如果您的安全上下文中有任何重要内容,例如用户帐户和Cookie,那么这是一个跨站点脚本安全漏洞。解决方法是作为附件和/或从不在主站点安全上下文中的不同主机名提供服务(通常使用子域)。

允许你不完全信任的用户上传文件到你的服务器,这实际上比PHP教程中的简单示例代码会让你相信更困难。 :-(

1

PHP Manual

$ _FILES [ 'userfile的'] [ '型']

的MIME类型的文件,如果浏览器提供了这个信息。一个例子就是“image/gif”。然而,这种MIME类型在PHP方面没有被检查,因此不会将其值视为理所当然。

我不会相信任何用户或用户的浏览器发送给我的东西。

如果您正在尝试学习,我会查看现有的安全来源,例如来自PEAR的HTTP_Upload。你甚至可以考虑使用Beta版本。

+1

感谢这一点,但您的链接是给404未找到错误! – user153887 2009-11-02 19:40:03

+0

对我的作品......没有'ca2.'前缀的作品,也。链接*没有被破坏,它可能在你的结尾被阻止。 – pavium 2009-11-02 19:56:22

+0

PEAR链接是404也是。 – 2009-11-02 21:02:42

0

除了上述文章中,我们依靠FileInfoSplFileInfo,到目前为止,它已被证明是满足我们需要的最好的选择。

0

OK,在图像的情况下,我们可以使用getimagesize($_FILES['userfile']['tmp_name']); 和可以验证他们,但什么的ZIPRARPDF文件呢?