【问题标题】:protect php includes (with htaccess?)保护 php 包括(使用 htaccess?)
【发布时间】:2012-06-11 00:18:26
【问题描述】:

首先,我很确定 Stack Overflow 上会出现类似的问题,但我并没有真正找到它。可能是因为我使用了错误的关键字。所以不要因此而开枪打我。

我的问题基本上是,我想包含 php 文件,但我只想包含它们,而不是让人们用浏览器打开它们。他们应该得到一个错误。

例如,我有一个包含 php 文件的包含目录,其中包含我与数据库的连接(密码等。危险?)。我希望能够包含它,但我不希望人们直接访问该页面。

使用 htaccess 在包含目录上设置密码可以解决我的问题吗?首先我认为它不会,因为可以为无权访问它的用户包含页面会很奇怪。但这似乎有效,这是怎么来的?还有其他更好的选择吗? Web 开发人员通常做什么?

我也可以为 javascript 文件做类似的事情吗?我的猜测是不会是这种情况,但我只是在问。该js文件包含对某些页面的ajax调用,但我想如果我能保护php页面不被访问,我会很高兴。

无论如何提前谢谢:)

【问题讨论】:

  • 只要你安装了php并正确配置了apache,访问任何.php的人只会看到你回显的内容
  • 请注意,您为什么担心人们看到您的 PHP 文件的内容?即使如果他们尝试通过浏览器下载它们,他们得到的只是这些脚本的输出(即任何你“回显”的东西)。
  • 如果我不回显,他们绝对看不到php文件的内容吗?我不是 100% 确定这一点。基本上,我想我更喜欢白页上方的错误。
  • @gl3nn - 当您在开发系统上时,错误消息比白页更可取。当您在实时网站上时,最好有一个白屏,以避免泄露有关该网站的安全详细信息。错误仍然记录在日志中。

标签: php .htaccess include protection


【解决方案1】:

嗯,如前所述,htaccess 不会阻止 php 访问 htpassword 安全文件夹。因此,必须调用 Apache 才能使用它非常安全的安全功能,至少对于 https 恕我直言,例如:

header('Location: secret/index.php');

文件夹机密使用 htaccess 保护。

index.php 可能如下所示:

<?php
$a = $_REQUEST['a'] ;
if ($a==secret)  
    header('Location: secret/index.php');    
include_once("index_head.php");
include_once("index_tail.php");
?>

还有secret/index.php

<?php 
include_once("../index_head.php");
include_once("./secret.php");
include_once("../index_tail.php");
?>

剩下的主要问题是,secret/index.php 找不到任何链接,如 ./main.css 等。因此链接必须定义为绝对而不是相对,但我相信你们现在该怎么做那个;-)

http://promotio.ch/secret.php/ 上有一个运行示例

【讨论】:

    【解决方案2】:

    您可以选择在不使用 .htaccess 的情况下执行此操作(并不是说这是一个更好的解决方案,只是一个不同的解决方案)。

    在您希望用户直接访问的文件中,将以下内容放在任何包含之前:

    @define('IN_APPLICATION', true);
    require 'file.class.php'; //sample include
    

    然后在包含(类文件)中,将以下代码放在顶部:

    if (!defined('IN_APPLICATION')){
        die(header('HTTP/1.0 404 Not Found')); //or just die();
    }
    

    这将确保类文件仅在包含在定义IN_APPLICATION 的文件(前端)中时才可访问。您也可以使用 die() 本身杀死类文件,而不是伪造 404。

    【讨论】:

    • 很好,但您不必定义常量。您可以使用“if (!function_exists('NAME'))”来检测文件是否被包含给定函数定义的 php 文件所包含。
    【解决方案3】:

    我认为解释这些部分如何协同工作将有助于消除混乱。

    请求进入(来自用户的网络浏览器)。您的 Web 服务器(在本例中为 Apache)接收此信息。首先,它检查&lt;Location&gt; 权限。然后它查看配置的其余部分,并最终将请求 URI 映射到文件系统。现在,它终于可以检查&lt;Directory&gt; 和.htaccess 的权限了。

    如果这些权限检查中的任何一个失败(例如,deny from all),Apache 将停止处理请求,并返回一个错误(或在 HTTP 基本身份验证的情况下请求用户名和密码)。

    一旦所有权限检查通过,Apache 就会查看该文件,并注意到它是一个.php 文件。在您(或您的网络主机)的 Apache 配置中,有一个 AddHandler 指令告诉 Apache 将此请求传递给 PHP 引擎(可以是 mod_php,或通过快速 cgi)。 (对于大多数文件,它会将文件的内容发送到浏览器。但脚本文件是特殊的,因为AddHandler。)

    现在,PHP 读取您的脚本文件。然后它还会直接读取您的包含文件。这不会通过 Apache 返回,因此 .htaccess 之类的内容不适用。这也意味着您的 PHP 包含 不 需要在您的文档根目录中。它们可以是 PHP 进程可以访问的任何地方(基于 UNIX 权限和 PHP 配置)。在你的 php.ini 中设置一个 include_dir 可以很容易地把它们放在任何地方。

    客户端 JavaScript 由用户的浏览器运行。它不是在服务器端解释的(就像 PHP 一样)。所以用户必须能够访问它,就像用户必须能够访问您的 .html 文件一样。

    所以,简而言之:

    • 您可以将.htaccess 和Deny from all 放在您的PHP 包含目录中。 PHP 的include 指令不通过Apache,所以它不会在意。理想情况下,您甚至根本不将 PHP 包含目录放在文档根目录下。
    • 您不能对 JavaScript 执行此操作,因为 JavaScript 访问通过 Apache(就像 .html、.png 等访问一样)。

    【讨论】:

    • 我了解除了 和 权限部分之外的所有内容。如果它们与 htaccess 无关(因为这是下一步),它们来自哪里?如何编辑它们? (并不是说我会这样做,但我很好奇它们是在哪里定义的。)
    • @gl3nn 它们位于主要的 Apache 配置中(通常在 /etc/apache 或 /etc/apache2 中,至少在 Linux 上)。如果您使用的是共享主机设置,则可能允许您在 VHost 配置中进行一些更改。
    • 是否有可能其他人将我网站中的带有函数的php文件包含到他们的php文件中,然后从中调用函数?
    • @gl3nn 如果他们对您的文件具有读取权限,那么他们可以。希望您的主机不允许这样做,至少默认情况下不允许。
    • 读取权限,如中,能看到文件中的php代码吗?我如何检查这一点,并确保不是这种情况?我尝试将主机中的页面包含到 localhost 文件中,但出现了一些错误,但我还不确定。
    【解决方案4】:

    理想情况下,您的 PHP 包含应位于网络无法直接访问的文件夹中。

    例如:假设您的网站在/var/www/htdocs/,那么您可以将index.php 放在那里,但包含应该在一个单独的文件夹中,在网络可访问区域之外。在此示例中,您可以在 htdocs 旁边有一个名为 /var/www/includes/ 之类的文件夹,PHP 包含在其中。

    这样他们就可以完全避免不必要的直接网络访问。

    此外,您应该编写 PHP 代码,使包含文件仅包含类或函数。这意味着如果从网络以某种方式访问​​它,则不会发生任何事情:PHP 将加载所有函数,但不会运行任何函数,因此用户只会看到一个空白页面。

    如果另一个页面想要包含该文件,则需要包含,然后还调用其中的函数;你不应该有一个立即运行代码的包含。

    您应该只编写在供用户直接访问的页面上立即运行的 PHP 代码,例如 index.php。

    希望对您有所帮助。

    【讨论】:

    • 如果我把文件放在根目录下,那么我的所有包含的功能是否真的有必要?对我的下一个项目来说似乎很聪明,但现在编辑所有内容似乎是一项漫长的工作。为你 +1。
    • @gl3nn - 是的,将文件移出网络可访问区域将在这方面保护它们。如上所述在函数中编写代码通常是一种很好的编程习惯,但如果您已经编写好东西,只需将它们放在安全的位置就足够了。
    • 将包含文件移到 Web 可访问目录之外有效,但与使用“php_value open_basedir ...”限制包含访问以提高安全性相冲突。它可能还需要更改将文件上传到服务器。下一个答案,测试一个包含文件是否真的被包含,可能会好一点。
    【解决方案5】:

    在您的包含目录中创建一个 .htaccess 文件

    deny from all
    

    不能为客户端脚本完成,因为浏览器必须能够访问它们。你能做的最好的就是obfuscate them。

    【讨论】:

    • 对 PHP(或许多服务器端脚本)的混淆是完全不需要且毫无意义的。
    • 我认为混淆部分是关于客户端脚本的。不过不确定。
    • 第二部分是关于客户端脚本的,因为这是 OP 问题的一部分。为什么我被否决了?
    • 我投了赞成票,因为我觉得混淆很有趣 :) 谢谢
    猜你喜欢
    • 1970-01-01
    • 2011-06-19
    • 2017-01-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-07-12
    • 1970-01-01
    相关资源
    最近更新 更多