文件上传时需要注意的安全步骤,因为它在保存在root中时容易受到攻击?

时间:2012-03-21 08:00:41

标签: php security file-upload open-source

我一直在通过各种教程和资源上传文件,发现上传到root或任何可通过Web访问的文件夹是一个安全问题,建议将上传文件夹保留在root用户之外。

现在,如果有人在 Godaddy 这样的共享托管服务器上,则用户将无权访问根文件夹。

如果真的什么也做不了,像Wordpress,Joomla,Drupal这些开源软件如何安全地保存他们的上传,并且几乎非常确定安全性?

所有必须注意的事情是,当条件是安全地在网络上保存数据时,我们只能选择将我们的文件保存在root中。

当您被迫将文件保存在公共可访问区域内时,我知道安全文件上传的清单如下: -

  1. 检查上传的文件大小和类型的功能。
  2. 存储文件时将文件重命名为一些随机名称,并通过数据库跟踪文件名,md5和sha1很棒。
  3. 使用.htaccess禁用脚本执行。

  4. 这是调用上传文件的示例: -

        // this is just example only to show how we can get the files
    
        $imgfile = $rsPhoto['photo']; // or value from database 
    
        list($width, $height, $type, $attr) = getimagesize($imgfile); 
    
        switch ($type)
        { 
    
        case 1: $im = imagecreatefromgif($imgfile);
        header("Content-type: image/gif");
        break; 
    
        case 2:
        $im = imagecreatefromjpeg($imgfile);
        header("Content-type: image/jpeg");
        break; 
    
        case 3:
        $im = imagecreatefrompng($imgfile);
        header("Content-type: image/png");
        break; 
    
        }
    

    这是一个例子,它不是关于保存少量图像文件和检索它,我们都知道数据被分类为任何商业成功的关键要素。所以当必须处理这类重要和重要数据时,我们有什么选择让事情尽可能完美和安全?

    参考文献: -


    编辑1:

    将域永久重定向到域的子文件夹是不是一个好主意......

    这样你的root就是/但是在重定向后你的root是/main-website/

    因此,如果我将我的上传文件夹保存在/upload/中,我认为它将被假定为在Web可访问/公共区域之外...... ??

    因此,我的域www.xyz.com指向/main-website/,并且上传文件夹超出了此域的范围......

    只是想到了我的想法,所以把它放了


    感谢。

4 个答案:

答案 0 :(得分:2)

我将假设上传的文件必须是全球可读的。我也会假设文件可以是任何类型:pdf,图像(pdf,png,ico),文档(docx,xl​​s)等

这里的最佳解决方案(通用不仅适用于PHP项目,而且适用于一般的Web项目)是添加一层复杂性或一层重定向:您将使用在服务器中自行生成的自定义名称保存文件,并使用BBDD存储原始文件名。

好的,让我们通过例子来看。想象一下,我们有这个目录:

/ -> Root. Its World Readable
/files -> Where we will store your files. World Readable too.

因此,当我将文件上传到名为“foo.png”的站点时,您将其保存到“/ files”目录,但您必须将我的文件名更改为自动生成的文件[1]。让我们说“1234asd”。您必须使用新的自动生成的文件名(“foo.png”)在BBDD中写入新记录。所以...现在,¿如果我不知道新名字怎么能下载我的文件?

好吧,你必须在服务器中创建“/file.php”,它将接受名为“filename”的GET参数。然后我可以这样做:“/ file.php?filename = foo.png”,你的代码将执行以下操作:

  • 在BBDD中搜索文件“foo.png”是否存在。如果存在,请获取真实文件名。如果不存在,则返回404 HTTP代码。
  • 然后从 direcory “/ files / 1234asd”中读取该文件并将其返回给用户

这样,可以将任何类型的文件上传到您的服务器(* .php文件),并且您是安全的,因为文件不是直接访问的,而是抛弃您PHP代码(file.php)。

这提供了额外的优势,例如能够检查用户是否有权读取他请求的文件(通过实现某种简单的身份验证)。如果找不到该文件而不是返回一个丑陋的404 HTTP代码(在这种情况下这是正确的事情)你可以返回一个自定义错误消息“ooops!404 - 你请求的文件不可用”或类似的东西这一点。

注意:此解决方案适用于0到10 ...... 20MB的文件。如果您正在使用较大的文件,则此解决方案不是最佳的,应采用另一种方法。

[1] http://php.net/manual/en/function.uniqid.php

答案 1 :(得分:1)

这是一个链接(谷歌缓存文本版本)一篇有助于保护wordpress的文章。

http://webcache.googleusercontent.com/search?q=cache:V5RddpaOH4IJ:gerry.ws/2008/10/152/setup-and-secure-your-wordpress-upload-directory.html&hl=en&gl=au&strip=1

(我已经链接到谷歌缓存版本,因为他们的网站使我的chrome / firefox锁定,文本只是没有)。

基本上,您将上传内容放在只有应用可以访问它的位置(在网络位置的上方或外部),然后:

  • 限制可以上传的文件的mimetypes(并验证文件以确保它们不包含已知的缓冲区溢出,exif poisining,嵌入式可执行文件等漏洞利用)
  • 确保您不允许使用父路径
  • 确保您的上传路径计算在服务器端运行,而不是通过某种隐藏的表单字段等
  • 确保您的服务器平台(例如php / apache)的执行访问权限不会在该位置执行
  • 确保只有网络服务器(例如apache)帐户才有权写入该位置
  • 确保您的脚本验证上传中发布的数据

另见:http://codex.wordpress.org/Hardening_WordPress

答案 2 :(得分:1)

除了在将文件上传到服务器时检查文件的方法,例如:检查扩展名/ mimetype,限制上传大小...我还有更多提示。

当我使用共享主机时:在上传文件夹中关闭php执行,你可以使用htaccess和php_flag = off。

当我有专用服务器时:设置存储而不执行任何脚本(php)并通过ftp上传文件。

答案 3 :(得分:1)

虽然您可能无法访问root之外的任何其他文件夹,但通常在共享主机上您可以访问您的主目录。 我已经在我拥有的服务器上进行了测试,我可以在/ home / myuser上存储文件,这些文件可能位于webroot之外(通常位于/ home / youruser / www)。 此外,您可以使用/ tmp,这对每个人都是可写的,但是如果您这样做,请不要在那里存储敏感数据,因为所有hoster用户都可以读取它。