【问题标题】:Basic CHMOD restriction [closed]基本 CHMOD 限制
【发布时间】:2012-04-12 14:16:30
【问题描述】:

我的网站上有一个上传文件夹。 我想要做的是限制用户访问,就像我不希望他们去 www.mysite.com/uploads/ 并查看那里的文件,它应该显示被禁止,但他们应该能够通过我的网站下载,因为例如 www.mysite.com/downloads.php?id=1

如果那不可能,我怎么能至少不向他们显示 /uploads 上的目录索引

文件共享网站是如何做到的?

一个htaccess与

deny from all

也停止 php 访问文件
如果您知道,请告诉我一个解决方案,我几天前在 irc 上搜索并询问了这个问题,这让我很困惑。

【问题讨论】:

  • 把文件夹放到web根目录外,问题解决了。
  • 你的意思是外部 /public_html/ ?
  • 是的。这就是我们大多数人的做法
  • 通过默默无闻的安全性永远不是答案。换句话说,我希望 downloads.php 有某种形式的授权处理。否则没有什么可以阻止某人尝试?id=...的多种组合
  • 为@Dragon +1。不要乱用 chmod 功能。我已经尝试了所有限制外部文件的方法。最好的方法是将文件放在 webroot 后面。

标签: php .htaccess file-upload chmod file-sharing


【解决方案1】:

在您的 .htaccess 文件中添加这一行

Options -Indexes

【讨论】:

    【解决方案2】:

    在您的上传文件夹中放置一个 index.htm 文件或在您的 .htaccess 文件中放置 Options -Indexes

    【讨论】:

      【解决方案3】:

      如果您想对用户隐藏您的文件 url,最好将 upload folder 移动到您的 webroot 目录上方。所以没有人可以从浏览器访问。你是如何制作download.php

      <?php
      
       /*
          Step 1. Authorization check
          Step 2. get name or id of file that will download $_GET
          Step 3. check if its valid (security check)
          Step 4. check if that file exist in your upload directory
          Step 5. set header using header() function put content-type, attachment etc
          Step 6. readfile and output it
       */
       ?>
      

      【讨论】:

      • +1 但值得一提的是用户身份验证,否则它对正确的 Web 服务器配置没有实际价值。
      • @cbuckley 谢谢,对于这种情况,是的,你是对的。但是当它提供动态和临时下载链接(如 OP 提到的共享托管网站)和隐藏文件的真实路径时很有用。
      • 我知道如何让用户下载文件的唯一方法是将他们链接到文件,我不确定如何执行您提到的第 5 步,有没有指南可以链接我?跨度>
      • @MarshallMathews 查看readfile 的文档。
      【解决方案4】:

      为什么不只是为可下载的东西(mkdir publicuploads)腾出一个地方,而是 chmod 700 你的上传文件夹? 然后他们可以下载您允许他们下载的内容...

      【讨论】:

      • 我的意思是,您基本上只是通过为公众创建一个单独的目录来主动选择公开上传的内容以及人们可以访问的内容。
      【解决方案5】:

      使用带有deny from all 的.htaccess 文件将阻止人们访问该文件夹,它不会阻止php 访问它,但是您可以将文件放在比htdocs/www/public_html 文件夹低一个目录并使用php 来获取和提供这些文件文件。

      通过传递参数,例如:?id=1,您将使用$_GET['id'] 访问1,您需要检查文件是否存在,添加一些http 标头以强制下载。

      这是一个您可以处理的简单示例:

      <?php 
      //your below webroot downloads folder
      $path="/var/www/somehost.com/downloads/";
      
      //An array created from globing the download directory or from a database source
      $files=array('somefile.gif',
                   'someotherFile.png');
      
      
      //In my example the id is the key to the file pathe array so 0 would be somefile.gif and 1 would be the next.
      if(isset($_GET['id'])){
          //Is it numeric?
          if(is_numeric($_GET['id']) && isset($files[$_GET['id']])){
              //Download the file, the download function will return error on fail, eg: not found or directory
              $status = download($path.$files[$_GET['id']]);
              //Spit out the error
              if(isset($status['error'])){
                  die($status['error']);
              }
          }
      }
      
      function download($file,$chunk=1024){
          if (file_exists($file)) {
              if(is_dir($file)){return array('error'=>'Not allowed!');}
              //Set content headers to force download.
              header('Content-Description: File Transfer');
              header('Content-Type: application/octet-stream');
              header('Content-Disposition: attachment; filename="'.str_ireplace(' ','_',basename($file)).'"');
              header('Content-Transfer-Encoding: binary');
              header('Connection: Keep-Alive');
              header('Expires: 0');
              header('Cache-Control: must-revalidate, post-check=0, pre-check=0');
              header('Pragma: public');
              //If download is larger the 2GB, alls not lost
              header('Content-Length: '.sprintf("%u", filesize($file)));
              //Clean the buffer
              ob_clean();
              //Open a handle to the file
              $handle = fopen($file, "rb");
              $chunksize=(sprintf("%u", filesize($file))/$chunk);
      
              set_time_limit(0);
              //Loop through the file 
              while (!feof($handle)) {
                          //Echo a piece of the file out
                  echo fgets($handle, $chunksize);
                  flush();
              }
              fclose($handle);
              die;
          }else{return array('error'=>'Not found!');}
          return;
      }
      ?>
      

      您还需要检查文件的用户权限,但这是另一个问题。

      【讨论】:

      • 你能评论你设置标题的部分吗,这样我就可以知道我在做什么:)
      • 这里有一份关于 php/http 标头的完整手册:php.net/manual/en/function.header.php 祝你好运。
      猜你喜欢
      • 1970-01-01
      • 2011-03-25
      • 2012-07-20
      • 2011-04-15
      • 1970-01-01
      • 2017-05-06
      • 2017-05-08
      • 2013-02-16
      • 2013-06-19
      相关资源
      最近更新 更多