阻止直接访问php包含文件
我有一个php文件,我将专门使用它作为include。因此,当直接通过键入URL而不是包含URL来访问时,我希望抛出一个错误,而不是执行它 基本上,我需要在php文件中进行如下检查:阻止直接访问php包含文件,php,include,include-guards,Php,Include,Include Guards,我有一个php文件,我将专门使用它作为include。因此,当直接通过键入URL而不是包含URL来访问时,我希望抛出一个错误,而不是执行它 基本上,我需要在php文件中进行如下检查: if ( $REQUEST_URL == $URL_OF_CURRENT_PAGE ) die ("Direct access not premitted"); 有没有一种简单的方法可以做到这一点?最简单的方法是在文件中设置一些调用include的变量,例如 $including = true; 然后在包含的文
if ( $REQUEST_URL == $URL_OF_CURRENT_PAGE ) die ("Direct access not premitted");
有没有一种简单的方法可以做到这一点?最简单的方法是在文件中设置一些调用include的变量,例如
$including = true;
然后在包含的文件中,检查变量
if (!$including) exit("direct access not permitted");
防止直接访问文件的最佳方法是将文件放在web服务器文档根目录之外(通常为一级以上)。您仍然可以包含它们,但不可能有人通过http请求访问它们
我通常会一直这样做,并将所有PHP文件放在文档根之外,而不是将-a lone index.PHP放在开始路由整个网站/应用程序的文档根中。对于通用的“在Apache服务器上运行的PHP应用程序,您可以完全控制,也可以不完全控制”,这是最简单的方法这种情况是将include放在一个目录中,并拒绝对.htaccess文件中该目录的访问。为了避免人们使用谷歌搜索的麻烦,如果您使用的是Apache,请将其放入一个名为“.htaccess”的文件中,该文件位于您不希望访问的目录中:
Deny from all
如果你真的完全控制了服务器(现在即使是小应用也比我第一次写这个答案时更常见),最好的方法是将你想要保护的文件粘贴到你的web服务器所服务的目录之外。因此,如果您的应用程序位于
/srv/YourApp/
中,请将服务器设置为服务/srv/YourApp/app/
中的文件,并将包含内容放入/srv/YourApp/includes
中,这样实际上就没有任何URL可以访问它们。将其添加到您只希望包含的页面中
<?php
if(!defined('MyConst')) {
die('Direct access not permitted');
}
?>
然后在包含它的页面上添加
<?php
define('MyConst', TRUE);
?>
执行以下操作:
<?php
if ($_SERVER['SCRIPT_FILENAME'] == '<path to php include file>') {
header('HTTP/1.0 403 Forbidden');
exit('Forbidden');
}
?>
Chuck解决方案的另一个替代方案(或补充方案)是通过在.htaccess文件中添加类似内容来拒绝访问与特定模式匹配的文件
<FilesMatch "\.(inc)$">
Order deny,allow
Deny from all
</FilesMatch>
命令拒绝,允许
全盘否定
实际上,我的建议是执行所有这些最佳实践
- 将文档放在webroot之外或Web服务器拒绝访问的目录中 及
- 在隐藏文档检查的可见文档中使用定义:
这样,如果文件不知何故被放错了位置(一个错误的ftp操作),它们仍然受到保护。我有一个文件,当它被包含时和直接访问时(主要是一个
print()
vsreturn()
)我需要采取不同的操作。下面是一些修改后的代码:
if(count(get_included_files()) ==1) exit("Direct access not permitted.");
正在访问的文件始终是包含的文件,因此==1 除了.htaccess方式之外,我在各种框架中看到了一种有用的模式,例如RubyonRails。它们在应用程序根目录中有一个单独的pub/目录,库目录位于与pub/相同级别的目录中。类似这样的情况(不理想,但你知道了): 您将web服务器设置为使用pub/as文档根目录。这为您的脚本提供了更好的保护:虽然它们可以从文档根目录中访问以加载必要的组件,但不可能从internet访问这些组件。除了安全之外的另一个好处是,一切都在一个地方
此设置优于仅在每个包含的文件中创建检查,因为“不允许访问”消息是攻击者的线索,并且优于.htaccess配置,因为它不是基于白名单的:如果您弄错了文件扩展名,它将在lib/中不可见,conf/etc.目录。我曾经遇到过这个问题,通过以下方法解决:
if (strpos($_SERVER['REQUEST_URI'], basename(__FILE__)) !== false) ...
但理想的解决方案是将文件放在web服务器文档根目录之外,如另一个anwser中所述。
What Joomla!does是在根文件中定义一个常量,并检查是否在包含的文件中定义了该常量
<?php
if (eregi("YOUR_INCLUDED_PHP_FILE_NAME", $_SERVER['PHP_SELF'])) {
die("<h4>You don't have right permission to access this file directly.</h4>");
}
?>
defined('_JEXEC') or die('Restricted access');
否则
正如大多数框架(如CodeIgniter)所建议的那样,可以将所有文件放在webroot目录之外,从而使它们不在http请求的范围内
甚至通过将.htaccess文件放入include文件夹并写入规则,也可以阻止直接访问。以下代码用于Flatnux CMS():
我发现这个仅适用于php且不变的解决方案同时适用于http和cli:
定义一个函数:
function forbidDirectAccess($file) {
$self = getcwd()."/".trim($_SERVER["PHP_SELF"], "/");
(substr_compare($file, $self, -strlen($self)) != 0) or die('Restricted access');
}
调用要阻止直接访问的文件中的函数:
forbidDirectAccess(__FILE__);
上述针对该问题的大多数解决方案都无法在Cli模式下工作。您可以使用下面的方法,但它确实存在缺陷,因为它可能是伪造的,除非您可以添加另一行代码以确保请求仅来自您的服务器,或者使用Javascript。
您可以将此代码放在HTML代码的主体部分,因此错误显示在那里
<?
if(!isset($_SERVER['HTTP_REQUEST'])) { include ('error_file.php'); }
else { ?>
将其他HTML代码放在此处
<? } ?>
这样结束它,这样错误的输出将始终显示在正文部分中,如果您希望这样做的话。出于安全原因,我建议不要使用$\u SERVER
。
debug_backtrace() || die ("Direct access not permitted");
您可以使用一个变量,如$root=true代码>在包含另一个文件的第一个文件中。
并在要包含的第二个文件的开头使用isset($root)
您还可以对目录进行密码保护,并将所有php脚本保存在目录中,当然,index.php文件除外,因为在使用include时,不需要密码,因为只有http访问才需要密码。它将为您提供访问脚本的选项,以防您需要它,因为您将拥有访问该目录的密码。您需要为目录设置.htaccess文件和.htpasswd文件以验证用户身份。forbidDirectAccess(__FILE__);
<?
if(!isset($_SERVER['HTTP_REQUEST'])) { include ('error_file.php'); }
else { ?>
<? } ?>
debug_backtrace() || die ("Direct access not permitted");
define(A,true);
defined('A') or die(header('HTTP/1.0 403 Forbidden'));
if (basename($_SERVER['PHP_SELF']) == basename(__FILE__)) { die('Access denied'); };
/**
* Hmmm... why is my netbeans debugger only showing a blank white page
* for this script (that is being tested outside the framework)?
* Later... I just don't understand why my code is not working...
* Much later... There are no error messages or anything!
* Why is it not working!?!
* I HATE PHP!!!
*
* Scroll back to the top of my 100s of lines of code...
* U_U
*
* Sorry PHP. I didn't mean what I said. I was just upset.
*/
// defined('_JEXEC') or die();
class perfectlyWorkingCode {}
perfectlyWorkingCode::nowDoingStuffBecauseIRememberedToCommentOutTheDie();
<?php
$url = 'http://' . $_SERVER['SERVER_NAME'] . $_SERVER['REQUEST_URI'];
if (false !== strpos($url,'.php')) {
die ("Direct access not premitted");
}
?>
if( count(get_included_files()) == ((version_compare(PHP_VERSION, '5.0.0', '>='))?1:0) )
{
exit('Restricted Access');
}
// In the base page (directly accessed):
define('_DEFVAR', 1);
// In the include files (where direct access isn't permitted):
defined('_DEFVAR') or exit('Restricted Access');
// Put the code in a separate file instead, say 'checkdefined.php':
defined('_DEFVAR') or exit('Restricted Access');
// Replace the same code in the include files with:
require_once('checkdefined.php');
// Call the include from the base page(directly accessed):
$includeData = file_get_contents("http://127.0.0.1/component.php?auth=token");
// In the include files (where direct access isn't permitted):
$src = $_SERVER['REMOTE_ADDR']; // Get the source address
$auth = authoriseIP($src); // Authorisation algorithm
if( !$auth ) exit('Restricted Access');
if($key!="serv97602"){header("Location: ".$dart);exit();}
//Your secure dir path based on server file-system
$secure_dir=dirname($_SERVER['DOCUMENT_ROOT']).DIRECTORY_SEPARATOR."secure".DIRECTORY_SEPARATOR;
include($secure_dir."securepage.php");
if (array_search(__FILE__, get_included_files()) === 0) {
echo 'direct access';
}
else {
echo 'included';
}
$currentFileInfo = pathinfo(__FILE__);
$requestInfo = pathinfo($_SERVER['REQUEST_URI']);
if($currentFileInfo['basename'] == $requestInfo['basename']){
// direct access to file
}
if ( ! defined('BASEPATH')) exit('No direct script access allowed');
$max_includes = version_compare(PHP_VERSION, '5', '<') ? 0 : 1;
if (count(get_included_files()) <= $max_includes)
{
exit('Direct access is not allowed.');
}
if (empty($_SERVER["HTTP_X_REQUESTED_WITH"]) && $_SERVER["HTTP_X_REQUESTED_WITH"] != "XMLHttpRequest") {
if (realpath($_SERVER["SCRIPT_FILENAME"]) == __FILE__) { // direct access denied
header("Location: /403");
exit;
}
}
<?php
function a() {
// function body
}
function b() {
// function body
}