インクルードとしてのみ使用するphpファイルがあります。したがって、URLを入力して直接アクセスした場合は、実行する代わりにエラーをスローしたいと思います。
基本的に、phpファイルで次のようにチェックする必要があります。
if ( $REQUEST_URL == $URL_OF_CURRENT_PAGE ) die ("Direct access not premitted");
これを行う簡単な方法はありますか?
インクルードとしてのみ使用するphpファイルがあります。したがって、URLを入力して直接アクセスした場合は、実行する代わりにエラーをスローしたいと思います。
基本的に、phpファイルで次のようにチェックする必要があります。
if ( $REQUEST_URL == $URL_OF_CURRENT_PAGE ) die ("Direct access not premitted");
これを行う簡単な方法はありますか?
これを含めたいページに追加します
<?php
if(!defined('MyConst')) {
die('Direct access not permitted');
}
?>
次に、それを含むページに追加します
<?php
define('MyConst', TRUE);
?>
一般的な「Apache サーバー上で実行されている PHP アプリを完全に制御できる場合と制御できない場合」の最も簡単な方法は、インクルードをディレクトリに配置し、.htaccess ファイルでそのディレクトリへのアクセスを拒否することです。Google を使う手間を省くために、Apache を使用している場合は、これを「.htaccess」という名前のファイルに入れ、アクセスしたくないディレクトリに置きます。
Deny from all
実際にサーバーを完全に制御している場合 (私が最初にこの回答を書いたときよりも、最近では小さなアプリでもより一般的です)、最善の方法は、保護したいファイルを Web サーバーが提供しているディレクトリの外に置くことです。 . したがって、アプリが にある場合は、/srv/YourApp/
ファイルを提供するようにサーバーを設定し、インクルードを/srv/YourApp/app/
に配置し/srv/YourApp/includes
ます。文字通り、それらにアクセスできる URL はありません。
含まれている場合と直接アクセスされている場合(主に a print()
vs return()
)で異なる動作をする必要があるファイルがあります。変更されたコードは次のとおりです。
if(count(get_included_files()) ==1) exit("Direct access not permitted.");
アクセスされるファイルは常にインクルード ファイルであるため、== 1 になります。
ファイルへの直接アクセスを防ぐ最善の方法は、ファイルを Web サーバーのドキュメント ルートの外 (通常は 1 レベル上) に配置することです。それらを含めることはできますが、誰かが http 要求を介してそれらにアクセスする可能性はありません。
私は通常、すべての PHP ファイルをドキュメント ルートの外に配置します。ブートストラップ ファイルは別として、ウェブサイト/アプリケーション全体のルーティングを開始するドキュメント ルート内の唯一の index.php です。
Chuck のソリューションの代替 (または補完) は、.htaccess ファイルに次のようなものを配置して、特定のパターンに一致するファイルへのアクセスを拒否することです。
<FilesMatch "\.(inc)$">
Order deny,allow
Deny from all
</FilesMatch>
実際、私のアドバイスは、これらのベスト プラクティスをすべて実行することです。
if (!defined(INCL_FILE_FOO)) {
header('HTTP/1.0 403 Forbidden');
exit;
}
このようにして、ファイルが何らかの形で置き忘れられた場合 (誤った ftp 操作)、ファイルは引き続き保護されます。
私は一度この問題を抱えていましたが、次の方法で解決しました:
if (strpos($_SERVER['REQUEST_URI'], basename(__FILE__)) !== false) ...
しかし、理想的な解決策は、別の anwser で述べられているように、ファイルを Web サーバー ドキュメント ルートの外に配置することです。
入口が 1 つであるアプリケーションを作成することをお勧めします。つまり、すべてのファイルは index.php からアクセスする必要があります。
これをindex.phpに配置します
define(A,true);
このチェックは、リンクされた各ファイルで実行する必要があります (require または include を介して)
defined('A') or die(header('HTTP/1.0 403 Forbidden'));
debug_backtrace() || die ("Direct access not permitted");
最も簡単な方法は、呼び出しがインクルードするファイルに変数を設定することです。
$including = true;
次に、含まれているファイルで、変数を確認します
if (!$including) exit("direct access not permitted");
何Joomla!ルートファイルで定数を定義し、インクルードファイルで同じものが定義されているかどうかを確認します。
defined('_JEXEC') or die('Restricted access');
またはそうでなければ
CodeIgniter などのほとんどのフレームワークが推奨するように、すべてのファイルを webroot ディレクトリの外に配置することで、http 要求の範囲外にすべてのファイルを保持できます。
または、インクルード フォルダー内に .htaccess ファイルを配置してルールを記述することでも、直接アクセスを防ぐことができます。
.htaccess の方法以外にも、Ruby on Rails など、さまざまなフレームワークで便利なパターンを見てきました。アプリケーションのルート ディレクトリに別の pub/ ディレクトリがあり、ライブラリ ディレクトリはpub/と同じレベルのディレクトリにあります。このようなもの(理想的ではありませんが、アイデアは得られます):
app/
|
+--pub/
|
+--lib/
|
+--conf/
|
+--models/
|
+--views/
|
+--controllers/
pub/ をドキュメント ルートとして使用するように Web サーバーを設定します。これにより、スクリプトの保護が強化されます。スクリプトはドキュメント ルートからアクセスして必要なコンポーネントをロードできますが、インターネットからコンポーネントにアクセスすることはできません。セキュリティ以外のもう 1 つの利点は、すべてが 1 か所にあることです。
このセットアップは、「アクセスが許可されていません」というメッセージが攻撃者の手がかりになるため、含まれるすべてのファイルにチェックを作成するよりも優れています。また、ホワイトリストベースではないため、.htaccess 構成よりも優れています。 lib/、conf/ などのディレクトリには表示されません。
より正確に言えば、次の条件を使用する必要があります。
if (array_search(__FILE__, get_included_files()) === 0) {
echo 'direct access';
}
else {
echo 'included';
}
get_included_files()は、インクルードされたすべてのファイルの名前を含むインデックス付き配列を返します (ファイルが実行された場合、ファイルはインクルードされ、その名前は配列内にあります)。そのため、ファイルに直接アクセスすると、その名前が配列の最初になり、配列内の他のすべてのファイルが含まれます。
http と cli の両方で機能するこのphpのみの不変のソリューションを見つけました:
関数を定義します:
function forbidDirectAccess($file) {
$self = getcwd()."/".trim($_SERVER["PHP_SELF"], "/");
(substr_compare($file, $self, -strlen($self)) != 0) or die('Restricted access');
}
への直接アクセスを防止するファイルで関数を呼び出します。
forbidDirectAccess(__FILE__);
この質問に対する上記の解決策のほとんどは、Cli モードでは機能しません。
<?php
$url = 'http://' . $_SERVER['SERVER_NAME'] . $_SERVER['REQUEST_URI'];
if (false !== strpos($url,'.php')) {
die ("Direct access not premitted");
}
?>
if (basename($_SERVER['PHP_SELF']) == basename(__FILE__)) { die('Access denied'); };
<?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>");
}
?>
上記のコードを、インクルードされた php ファイルの先頭に配置します。
元:
<?php
if (eregi("some_functions.php", $_SERVER['PHP_SELF'])) {
die("<h4>You don't have right permission to access this file directly.</h4>");
}
// do something
?>
次のコードは、Flatnux CMS ( http://flatnux.altervista.org )で使用されます。
if ( strpos(strtolower($_SERVER['SCRIPT_NAME']),strtolower(basename(__FILE__))) )
{
header("Location: ../../index.php");
die("...");
}
次のようにします。
<?php
if ($_SERVER['SCRIPT_FILENAME'] == '<path to php include file>') {
header('HTTP/1.0 403 Forbidden');
exit('Forbidden');
}
?>
以下の方法を使用できますが、Javascriptを使用してリクエストがサーバーからのみ送信されるように別のコード行を追加できる場合を除いて、偽造される可能性があるため、欠陥があります。このコードをHTMLコードのBodyセクションに配置できるため、エラーが表示されます。
<?
if(!isset($_SERVER['HTTP_REQUEST'])) { include ('error_file.php'); }
else { ?>
他のHTMLコードをここに配置します
<? } ?>
このように終了すると、エラーの出力が常にbodyセクション内に表示されます(希望する場合)。
また、ディレクトリをパスワードで保護し、index.php ファイルを除くすべての php スクリプトをそこに保持することもできます。それが行うことは、そのディレクトリにアクセスするためのパスワードがあるため、必要に応じてスクリプトにアクセスするオプションを提供することです。ディレクトリ用の .htaccess ファイルと、ユーザーを認証するための .htpasswd ファイルをセットアップする必要があります。
cPanelなどからいつでもアクセスできるため、通常はこれらのファイルにアクセスする必要がないと思われる場合は、上記のソリューションのいずれかを使用することもできます.
お役に立てれば
PHPバージョンチェックが追加された前述のソリューション:
$max_includes = version_compare(PHP_VERSION, '5', '<') ? 0 : 1;
if (count(get_included_files()) <= $max_includes)
{
exit('Direct access is not allowed.');
}
ユーザーにアクセスを許可したいフォルダ内の他のコンテンツをブロックする可能性があるため、 .htaccess の提案はあまり良くありませんでした。これが私の解決策です:
$currentFileInfo = pathinfo(__FILE__);
$requestInfo = pathinfo($_SERVER['REQUEST_URI']);
if($currentFileInfo['basename'] == $requestInfo['basename']){
// direct access to file
}
phpMyAdmin スタイルを使用できます。
/**
* block attempts to directly run this script
*/
if (getcwd() == dirname(__FILE__)) {
die('Attack stopped');
}
$_SERVER
セキュリティ上の理由から を使用しないことをお勧めします。別の変数を含む最初のファイル
のような変数を使用できます。
インクルードされる 2 番目のファイルの先頭で使用します。 $root=true;
isset($root)
if ( ! defined('BASEPATH')) exit('No direct script access allowed');
スムーズに仕事をしてくれる
他のユーザーがアクセスできないようにするドキュメントの名前を変更することもできます。たとえば、名前を 47d8498d3w.php に変更できます。人々がおそらく http-request として入力しないようなものを作ってください。SSI または PHP を使用してファイルを含めると、ユーザーはドキュメントの名前を見ることができなくなります。