【问题标题】:how to protect server directory using .htaccess如何使用 .htaccess 保护服务器目录
【发布时间】:2010-12-27 04:56:58
【问题描述】:

我设计了一个网站,其中包含一系列与我的系统交互的 PHP 脚本。例如,如果用户上传了一张图片,这是由脚本处理的

image.php 

如果用户登录,则由脚本处理

login.php

所有这些脚本都存储在名为:scripts 的文件夹中

如何确保有人无法访问这些页面,但仍确保系统可以使用它们?我想确保 PHP 页面将接受 post 值、获取值并可以重定向到其他页面,但不能通过地址栏直接访问或下载?

我尝试使用 deny from allLimit GET, POST 阻止使用 .htaccess 的访问,但这阻止了系统工作,因为我根本无法访问这些文件。

【问题讨论】:

  • “已处理”是什么意思?是包含这些文件还是 HTML 表单的目标?
  • 在后一种情况下,你不能做任何事情(除了检查一个空的$_POST变量)。

标签: php .htaccess directory


【解决方案1】:

您可以在 .htaccess 上设置拒绝所有文件,并从某个可访问目录中包含这些文件

【讨论】:

    【解决方案2】:

    您不能真正阻止对文件的直接请求,并且仍然让其他请求可以访问它们。您能做的最好的事情就是掩盖它们的位置,并控制如何访问它们。

    您可以采用的一种方法是创建一个 PHP“切换”脚本,该脚本将为您包含这些脚本,而不是让 Apache 直接请求它们。

    例如,如果您将 scripts/image.php 规则目标改为 switch.php?file=image.php,则有点像:

    RewriteRule ([^\.]+\.(jpe?g|png|gif)$ switch.php?file=image.php&rw=1&meta=$1 [L,QSA]
    

    您可以将deny from all 添加到scripts/.htaccess 文件中,然后在您的switch.php 文件中执行此操作。

    <?php
    /** File: switch.php **/
    $allowed_files = array(
        'login.php',
        'image.php'
    );
    $script_dir = 'scripts/';
    if(isset($_POST['rw']) && in_array($_REQUEST['file'], $allowed_files)) {
        include $script_dir . $allowed_files[$_REQUEST['file']];
    }
    else {
        header('HTTP/1.1 404 File Not Found');
        include 'error404.html'; // Or something to that effect.
    }
    ?>
    

    $_POST['rw'] 有一个弱检查,以查看规则是否来自 RewriteRule,旨在防止对文件的直接请求。如果你知道它在那里很容易绕过,但对机器人等的随机请求有效。

    这样,对scripts/image.phpswitch.php?file=image.php 的直接请求将失败,但对任何图像文件的请求都会触发scripts/image.php 脚本。

    【讨论】:

      【解决方案3】:

      使用 htaccess 阻止文件使请求者无法访问文件,例如页面的访问者。所以你需要一个代理文件来将访问者的请求传递给文件。为此,请查看MVC patternFront Controller pattern

      基本上,您要做的是将所有请求路由到单个入口点,例如index.php 并从那里决定调用哪个操作(您的脚本)来处理请求。然后,您可以将您的脚本和模板放在可公开访问的文件夹之外,或者,如果这是不可能的(在某些共享主机上),则使用 htaccess 保护文件夹,就像您已经做过的那样(全部拒绝)。

      要使用上传脚本,您需要一个类似http://example.com/index.php?action=upload 的网址。

      一个超级简单的 FrontController 就这么简单

      $scriptPath      = 'path/to/your/scripts/directory/';
      $defaultAction   = 'action404.php';
      $requestedAction = $_GET['action']; // you might want to sanitize this
      
      switch($action) {
          case 'upload':
              $actionScript = 'image.php';
              break;
          case 'login':
              $actionScript = 'login.php';
              break;
          default:
              $actionScript = $defaultAction;
      }
      include $scriptPath . $actionScript;
      exit;
      

      然后,您的 actionScript 将执行您需要对请求执行的所有操作,包括重定向、数据库访问、身份验证、上传内容、呈现模板等 - 任何您认为必要的操作。上例中的默认操作可能如下所示:

      <?php // action404.php
          header('HTTP/1.1 404 File Not Found');
          fpassthru('path/to/template/directory/error404.html');
      

      numerous implementations of the FrontController pattern in PHP。有些简单,有些复杂。 CodeIgniter framework 使用轻量级的 MVC/FrontController 实现,如果这对您来说是新的,它可能不会太大。

      就像上面建议的 Atli 一样,您可以使用mod_rewrite 来强制所有对 index.php 的请求,您也可以使用它来美化您的 URL。这是 MVC 框架的常见做法,已在此处和其他地方广泛介绍。

      【讨论】:

        【解决方案4】:

        我想确保 PHP 页面将接受 post 值、获取值并可以重定向到其他页面,但不能通过地址栏直接访问或下载?

        只要将 Apache 配置为将所有 .php 文件与 PHP 应用程序相关联,就没有人可以下载 PHP 内容本身。因此,如果有人浏览到“mysite.com/image.php”,PHP 就会运行。用户不会看到您的 PHP 内容。

        这应该已经在你的 httpd.conf 文件中完成了:

        • AddType application/x-httpd-php .php .phtml

        现在,image.php 将期待某些帖子参数。如果没有像 Atli 上面建议的那样实现 MVC 架构,您可以优雅而安全地处理任何未提供的缺失参数。然后,用户可以直接访问该页面,但不能对其进行任何操作。

        【讨论】:

          【解决方案5】:

          许多应用程序只是将文件(如脚本)放在公共文件夹(如 /public_html/ 或 /www/)中,而不是放在与您的公共文件夹相同的根文件夹中。

          所以没有 root/public_html/ 和 root/public_html/scripts/

          但是 root/public_html/ 和 根/脚本/

          访问者无法访问公共文件夹上方文件夹中的任何内容,但通过在 /public_html/index.php 中指定文件 '../scripts/yourscript.php' PHP 可以访问这些文件和访问者不能。 (文件夹 ../ 表示“在文件夹层次结构中上一层”)

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 2012-08-21
            • 2012-08-12
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2018-08-30
            • 1970-01-01
            相关资源
            最近更新 更多