【问题标题】:Upload files outside of webroot在 webroot 之外上传文件
【发布时间】:2009-09-16 13:50:26
【问题描述】:

我正在开发一个购物系统,其中 shopmanager 应该能够将文件上传到系统。这些文件可以收费出售,并且只能通过提供购买代码才能访问。

整个购买代码和上传工作正常。只需阻止对文件的直接访问即可。

问题:

  • 如何允许用户在 webroot 之外上传,但不能从那里读取/下载?
  • 或者我如何允许用户上传到目录但没有人可以读取/下载?

我正在运行 Apache 并使用这样的代码通过表单上传文件:

 public function upload_file($file='',$post_value='',$path) {
  if ($_FILES[$post_value]) {
      $uploadext = strtolower(strrchr($_FILES[$post_value]['name'],"."));
      if($uploadext=='.jpg' || $uploadext=='.gif' || $uploadext=='.png' || $uploadext=='.swf' || $uploadext=='.jpeg' || $uploadext=='.pdf' || $uploadext=='.doc' || $uploadext=='.xls' || $uploadext=='.docx') {
    $destination = $path.$file.$uploadext;
       move_uploaded_file($_FILES[$post_value]['tmp_name'], $destination);
   } else {
    echo PICTURE_ERROR;
   }
  }
  return $file.$uploadext;
 }

【问题讨论】:

    标签: php forms file-upload


    【解决方案1】:

    你可以使用 move_uploaded_file 函数上传任何你想要的地方,只要确保网络服务器可以写入目标目录。

    在您必须创建一个脚本来读取文件并将其传递给浏览器之后,您可以确保用户已经支付了文件费用。

    例子

    <?php
    // insert your logic here to verify the user has access to this file.
    // open the file in a binary mode
    $name = 'yourfile';
    
    $fp = fopen($name, 'rb');
    
    // send the right headers
    header("Content-Type: image/png");
    header("Content-Length: " . filesize($name));
    
    // dump the picture and stop the script
    fpassthru($fp);
    exit;
    
    ?>
    

    如果您使用 $_GET 变量来获取文件名,您还必须注意内容类型,还要确保用户不能访问服务器的每个文件。

    【讨论】:

    • 这是最接近的答案。我创建了一个权限为 333 的目录并像这样使用 .htaccess 重定向:example.com/download/shhsfgoagoaag/1/ 指向一个 php 文件,该文件在下载后将所有内容作为参数解析。此外,提供的文件具有与原始名称相同的另一个名称。所以黑客必须知道准确的:原始文件名和目录(对目录的读取权限关闭)。店长仍然可以上传文件没有问题。由于基础限制,无法在 webroot 之外使用。
    【解决方案2】:

    这其实很简单。只需为您的文件创建一个目录并授予 apache 写入权限即可。然后,当您调用 move_uploaded_file() 函数时,您只需指定该目录的目标即可。 PHP 在服务器端运行,因此它能够访问该目录,而使用浏览器的用户将仅限于 Apache 允许他们访问的内容。

    如果您需要下载这些文件,只需创建一个解析 URL 参数(或其他内容)的脚本,然后从 files 目录中获取文件并将其推送到浏览器。

    【讨论】:

      【解决方案3】:

      使用.htaccess 文件或在 apache.conf 中配置以不允许直接访问上传目录。

      <Directory /path/to/upload/dir>
         Order Deny,Allow
         Deny from All
      </Directory>
      

      【讨论】:

        【解决方案4】:

        就保护文件而言,将文件保存在 webroot 之外可能是最简单的。当有人要下载时,您可以使用http_send_file 将文件发送回给他们。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2012-02-27
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2011-12-15
          相关资源
          最近更新 更多