【问题标题】:PHP protect directory from direct URL accessPHP 保护目录免受直接 URL 访问
【发布时间】:2013-01-03 11:19:12
【问题描述】:

我有一个 ADMIN 脚本。

admin/index.php

所有活动都是通过这个index.php 文件完成的。
用户在访问程序功能之前先登录。
$_SESSION['user_authenticated'] 已创建并设置为 true

admin/template/..

此文件夹包含imagescssjavascript 文件。
它们仅在此 ADMIN 中使用。 (仅在后端)

问题:

我需要保护admin/template/.. 目录中的所有内容不被直接访问
它应该只对经过身份验证的用户可用。

我猜肯定有一个.htaccess 将请求重定向到check_session_auth_variable.php,它查看$_SESSION['user_authenticated']true 还是false 并且重定向到请求的文件引发 404 错误

我知道最好的选择是将目录放在 Web 根目录之外,但在我的情况下,我需要保持目录结构不变。

【问题讨论】:

  • 最佳答案是:不要这样做。 提供对 css/js 文件的开放访问权限,保护 php 文件,使用 deny from all 保护子目录,仅此而已。很多流行的 wordpress 博客都可以访问/wp_admin/* (example),只要你的 php 文件中没有安全问题就可以了
  • 当未经授权的人看到任何图像、样式表或 JavaScript 文件时,为什么会很糟糕?里面有没有敏感数据?
  • @Peter Szymkowski 谢谢你的回答。感谢您提出使用deny from all 的想法,如有必要,我认为它可以与allow from IP 一起使用。
  • @Gumbo 不,这些文件中没有敏感数据,所以现在我可能会采用 Peter Szymkowski 建议的简单方法。

标签: php apache security .htaccess authentication


【解决方案1】:

我经常用这个

$redi_ext = $_SERVER['SERVER_NAME'].$_SERVER['REQUEST_URI'];
$php_verify = strpos($redi_ext, ".php");
if($php_verify !== false){ header('location: PAGE_NOT_FOUND_URL'); }

【讨论】:

    【解决方案2】:

    好的,这是我的答案 - 最好的答案确实是“不”。但是 images/js/css 在开发中相对重要(在上线之前公开),并且客户端预览表明我们不能执行基于 IP 的 apache 规则。所以,规则(从上面,稍微修改)是

    RewriteEngine On
    
    # Exclude the public and error directories from authentication
    RewriteRule ^(public|error)($|/) - [L]
    
    # Perform authentication via php
    RewriteCond %{REQUEST_FILENAME} !auth.php
    RewriteCond %{REQUEST_FILENAME} -f
    RewriteRule .* auth.php?requested_file=$0 [QSA,L]
    

    (因为我需要一些内容确实公开的子目录,请阅读:登录页面上使用的 images/css/js)

    相关的php如下;对于

            if($authenticated){
                if($extension == 'php'){    
    
                    call_user_func(function(){
    
                        $file_name = func_get_arg(0);
    
                        $path = getcwd();
                        chdir(pathinfo($file_name,PATHINFO_DIRNAME));
                        return include($file_name);
                        chdir($path);
    
                    }, $file_name);
    
                } else {
    
                    //set cache headers so the browsers don't have to refresh all the
                    // static content
                    header_remove('X-Powered-By');
                    header_remove('Transfer-Encoding');
                    header_remove('Cache-Control');
                    header_remove('Pragma');
                    header_remove('Expires');
                    //header('Expires:');
    
                    header('Content-type: '.$mime_type);
                    readfile($file_name);
                }
            }
    

    它的作用是使用call_user_func() 执行php 以停止命名空间污染,include() 执行PHP,并使用chdir() 确保脚本获得正确的当前工作目录。

    这就是“简单”的部分;内容标题和 mime 类型必须被“猜测”(我使用 finfo 作为 mime 类型,但它在 2013 年有一个错误,这只会加剧问题)但即使是 apache 也不能 100% 正确地做到这一点...

    然后删除图像的缓存控制标头,否则您不仅会经常像php页面一样...

    可以这么说;如果你有粗管道和很多你不需要的 cpu 周期,你只需要这样做......

    【讨论】:

      【解决方案3】:

      admin/.htaccess:

      RewriteCond %{REQUEST_FILENAME} !check_auth.php
      RewriteCond %{REQUEST_FILENAME} -f
      RewriteRule .* check_auth.php?file=$0 [QSA,L] # pass everything thru php
      

      管理员/check_auth.php:

      $file = $_GET['file'];
      if($_SESSION['user_authenticated']) {
          // please mind you need to add extra security checks here (see comments below)
          readfile($file); // if it's php include it. you may need to extend this code
      }else{
         // bad auth error
      }
      

      【讨论】:

      • 只是关于这个过程的一个注释:在流量很大的网站上这样做通常不是一个好主意,因为启动 PHP 线程来处理简单的文件读取的开销是 waaaaaaaay 超过让 Apache/IIS/etc 静态地提供内容。因此,如果您要在高流量管理面板上执行此操作,请记住这一点。 IMO 当涉及到管理面板的图形/JS 文件时,通过默默无闻的安全性通常就足够了。关闭 admin 文件夹的目录列表(无论如何您都应该这样做)。无论如何,JS/HTML 代码中不应该有任何“安全”的东西
      • @Brian 同意,这对于高流量管理面板来说是个坏主意。我们总能做的事情很少: 1. 将管理面板限制为几个 ip。 2. 清除漏洞中的 js 代码 3. 将管理面板目录名称更改为“/admin6234123312” :]
      • 还有一点需要注意的是,很明显你需要在readfile()ing 文件输出之前做一些额外的安全检查。由于 PHP/Apache 很可能可以访问服务器上的更多文件,这使得脚本可以被利用来访问用户不应该能够访问的文件。如果有人劫持了管理员会话,他们在技术上可以使用该文件以纯文本形式读取您网站上的任何文件(用户名、密码、数据库信息等)。当然,前提是他们知道文件路径。
      • 我的意思是 PHP 方面的更多。例如,如果我要请求该目录中的 .htaccess 文件,PHP 脚本可能有权读取它,并且它会通过 readfile 将文件内容输出给我。任何配置文件也是如此。此外,我可以在我的请求路径中使用 ../ 来遍历管理根目录之外并获取站点上的任何文件。
      • @PeterSzymkowski 不,不是。 check_auth.php?file=/etc/hosts 还是可以的。
      猜你喜欢
      • 2016-06-23
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-05-21
      • 1970-01-01
      • 2020-02-25
      • 2011-07-01
      • 1970-01-01
      相关资源
      最近更新 更多