【问题标题】:Allow php file only to be executed when included by another PHP file仅当被另一个 PHP 文件包含时才允许执行 php 文件
【发布时间】:2014-09-04 16:26:26
【问题描述】:

如果 PHP 文件包含在另一个 PHP 文件中,则只允许执行该文件的正确做法是什么?

例如,假设我有我的主应用程序文件“main.php”。该文件包括“settings.php”:

// www.mydomain.com/MAIN.PHP
<?php
require 'settings.php';
?>

// www.mydomain.com/SETTINGS.PHP
<?php
// DO SOMETHING
?>

如果用户从他们的浏览器运行“www.mydomain.com/SETTINGS.PHP”,我如何才能使“settings.php”不被执行?

我正在寻找仅 PHP 的解决方案。

【问题讨论】:

  • 简单:不要将其放入您网站的文档根目录中。如果您不希望它可用,请不要将它放在可用的地方。
  • 如果脚本只包含变量赋值,但不打印任何内容或修改服务器上的任何内容,如果有人执行它会有什么问题?他们看不到变量。
  • @Barmar - 这是一个很好的观点,但我想知道我的核心类和设置是隐藏的或无法访问的,除非我明确包含......
  • 然后就像@MarcB 说的,把它们放在他们无法访问的地方。
  • public_html 下您应该拥有的唯一文件是索引文件和资产,例如 Javascript、图像和 css。如果您的主目录中有 PHP 文件,您可能需要重新考虑您的应用程序及其工作方式。

标签: php


【解决方案1】:

第一个解决方案显然是不要将它放在网络可访问的位置。有时这是不可行的,因此您可以进行检查:

// www.mydomain.com/MAIN.PHP
<?php
define('SOMETHING', true);
require 'settings.php';


// www.mydomain.com/SETTINGS.PHP
<?php
if(!defined('SOMETHING')) { die(); }
// DO SOMETHING

或者您可以在全局头文件中使用类似的内容:

if(strpos($_SERVER["PHP_SELF"], basename(__FILE__) !== false) { die(); }

【讨论】:

  • 我认为这是我首选的纯 php 解决方案,因为将文件放在 webroot 之外需要一些服务器配置来删除 open_base_dir。
  • PHP_SELF 可以被欺骗吗?
【解决方案2】:

另一种方法是检查请求的文件(通常是$_SERVER['REQUEST_FILENAME'])是否匹配__FILE____FILE__ 设置为您当前所在文件的名称,即使在包含中也是如此。如果它们相同,那么您将直接加载文件。如果不同,则可以假定为包括在内。

【讨论】:

    【解决方案3】:

    一种方法是检查包含 settings.php 时设置的“神奇”值。

    // www.mydomain.com/MAIN.PHP
    <?php
    $magic = "c00f0c4675b91fb8b918e4079a0b1bac";
    require 'settings.php';
    ?>
    
    // www.mydomain.com/SETTINGS.PHP
    <?php
    if ($magic != "c00f0c4675b91fb8b918e4079a0b1bac") {
        die("Cannot be executed independently.");
    }
    // DO SOMETHING
    ?>
    

    这可以防止随意胡闹;它不会保护您免受可以读取您的 PHP 文件的人的攻击,可以访问您的服务器的人。

    【讨论】:

    【解决方案4】:

    settings.php中,可以检查$_SERVER['SCRIPT_FILENAME']是否为settings.php;如果是:直接访问脚本,如果不是:正在包含脚本

    //settings.php
    echo $_SERVER['SCRIPT_FILENAME']; // echoes 'settings.php'
    
    //file.php
    include 'settings.php'; //echoes 'file.php';
    

    这意味着你可以这样做:

    //settings.php
    if($_SERVER['SCRIPT_FILENAME'] != 'path/to/the/settings/file/settings.php'){
        define('SETTING', true);
    }
    

    【讨论】:

      【解决方案5】:

      如果要允许包含远程文件,必须在 php.ini 中将指令 allow_url_include 设置为 On

      See reference

      【讨论】:

      • 他不想包含远程文件。他想阻止包含文件作为普通网页访问。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-10-29
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多