【问题标题】:Building PHP uploader for gif/jpg/png/pdf/doc, wmv files, feasible, or should I buy something?为 gif/jpg/png/pdf/doc、wmv 文件构建 PHP 上传器,可行,还是我应该买东西?
【发布时间】:2010-10-13 16:58:28
【问题描述】:

我有一个 Mac 服务器,我正在构建 PHP 代码以允许用户上传图像、文档甚至视频文件。研究这个肯定让我很紧张,我希望上传的内容没有病毒。

自己构建东西会是一个巨大的挑战吗?你会这样做,还是会找到一些 OS 或 OTS 产品? (你知道有什么可以推荐的吗)?

【问题讨论】:

    标签: php security file upload


    【解决方案1】:

    从概念上讲,您所说的非常简单。接受和处理上传非常简单,我认为您绝对不需要担心购买预构建的解决方案。

    一般来说,像图像和视频这样的东西不会真的有“病毒”(除非查看器应用程序真的很差,让它们以某种方式运行代码 - 也称为“Internet Explorer”),但病毒扫描并不难无论如何,如果你愿意的话。只需找到一个可以在服务器上运行的命令行扫描程序(例如Clam AV),每当上传文件时,通过扫描程序运行它,如果扫描失败则拒绝上传(并记录事件)。

    【讨论】:

      【解决方案2】:

      如果您要上传非常大的文件,您还可以考虑使用 Flash 上传/状态栏,以便用户可以看到上传了多少文件。 SWFUpload 是一个不错的选择。

      您可以通过在 PHP 中执行以下操作来使用 ClamAV 扫描文件:

      
      $out = '';
      $int = -1;
      exec('/usr/local/bin/clamscan --stdout /path/to/file.ext', $out, $int);
      
      if ($int == 0)
      {
        print('No virus!');
      }
      
      /*
      Return codes from clamscan:
       0 : No virus found.
      
             1 : Virus(es) found.
      
             40: Unknown option passed.
      
             50: Database initialization error.
      
             52: Not supported file type.
      
             53: Can't open directory.
      
             54: Can't open file. (ofm)
      
             55: Error reading file. (ofm)
      
             56: Can't stat input file / directory.
      
             57: Can't get absolute path name of current working directory.
      
             58: I/O error, please check your file system.
      
             59: Can't get information about current user from /etc/passwd.
      
             60: Can't get information about user '' from /etc/passwd.
      
             61: Can't fork.
      
             62: Can't initialize logger.
      
             63: Can't create temporary files/directories (check permissions).
      
             64: Can't write to temporary directory (please specify another one).
      
             70: Can't allocate memory (calloc).
      
             71: Can't allocate memory (malloc).
      
      */
      
      

      【讨论】:

        【解决方案3】:

        简短的回答:不要买任何东西。自己编写代码所获得的经验和成就感更值得。

        长答案:相信任何形式的用户输入通常都是一个坏主意。但是,明智地处理用户数据始终是最好的方法。如果你不做傻事*,你会没事的,你会从经验中获益良多。



        ( * 我知道这有点模棱两可,但是,嘿,在你犯错之前尝试识别错误。我知道我很少能做到。;)

        【讨论】:

          【解决方案4】:

          我现在正在使用来自 digitarald 的 FancyUpload 为 Mootools 1.2.1 构建类似的东西

          查看此示例:http://localhost/fancyupload/showcase/photoqueue/ 看看它有多酷。

          只需确保您阅读了如何将会话传递给 Flash(使用 GET / POST 参数!您的会话 cookie 将不起作用。)并对文件类型进行一些检查。

          就我个人而言,我不会让我的用户上传视频。只需使用 youtube 并嵌入这些内容。

          哦,是的,如果您想获得上传内容的缩略图,请在您的服务器上安装 ImageMagick 和 Ghostscript。 Imagemagick 甚至可以从 PDF 生成缩略图!

          【讨论】:

            【解决方案5】:

            “我自己构建东西会是一个巨大的挑战吗?”是的。没有将其外包给第三方解决方案那么大,但是您想要在这里编码的可能是您可以在 php Web 脚本上编码的最危险的事情:允许用户将文件上传到您的服务器。您需要非常小心地过滤您要接受的文件,以防止用户将 php 脚本上传到您的服务器。人们在过滤时常犯的错误是:

            1. 根本不过滤。
            2. 基于错误正则表达式的过滤器很容易绕过。
            3. 不使用 is_uploaded_file 和 move_uploaded_file 函数可能会导致 LFI 漏洞。
            4. 不使用 $_FILES 数组(改为使用全局变量)可以访问 RFI 漏洞。
            5. 根据 $_FILES 数组中的类型进行过滤,因为它来自浏览器,所以可以伪造。
            6. 过滤器基于服务器端检查的 mime 类型,通过模拟魔术文件包含的内容来欺骗(即具有此内容 GIF8 的文件被识别为图像/gif 文件,但完美地作为 php 脚本执行)
            7. 将危险文件或扩展名列入黑名单,而不是将明确允许的文件或扩展名列入白名单。
            8. 不正确的 apache 设置允许上传重新定义 php 可执行扩展名(即 txt)的 .htaccess 文件..

            我可以继续,但我想你在问之前已经害怕了:)

            根据病毒问题,是的,只需运行 AV。

            【讨论】:

              【解决方案6】:

              这里是处理上传文件的代码,让你明白:

              foreach ($_FILES as $file) {
                if (!$file['error']) {
                  move_uploaded_file ($file['tmp_name'], 'uploads/'. $file['name']);
                } elseif (4 != $file['error']) {
                  $error_is = $file['error'];
                  // do something with the error :-)
                }
              }
              
              header ('Location: ...'); // go to the updated page, like, with the new files
              die;
              

              【讨论】:

                【解决方案7】:

                您最好使用第三方病毒扫描程序来确保上传的内容没有病毒。 (编写自己的代码来检查病毒听起来像是一项艰巨的任务)

                示例: 我认为 Gmail 使用的是 Norton,而 Yahoo!Mail 我认为使用的是 McAfee。

                【讨论】:

                  【解决方案8】:

                  Keith Palmer 建议使用小脚本。

                  使用 clamdscan 代替 clamscan。 clamdscan 与 setup clamd(clamav 守护程序)进行通信,而 clamscan 是一个独立的应用程序,因此每次调用它都会加载病毒签名,这可能会在您的服务器上产生相当大的负载。

                  此外,您还可以尝试使用 clamuko(这可以让您进行访问扫描),这样您就可以将文件拖放到 clamuko 观察到的目录中。

                  如果您不能将模块插入内核,还有基于 FUSE 的 ClamFS 可能是更好的解决方案。

                  【讨论】:

                    猜你喜欢
                    • 1970-01-01
                    • 1970-01-01
                    • 2012-12-21
                    • 2010-10-29
                    • 2014-06-21
                    • 2011-10-28
                    相关资源
                    最近更新 更多