web-dev-qa-db-ja.com

PHP:ファイルを含めるのではなく直接ロードするかどうかを確認しますか?

ユーザーがファイルを表示するのを防ぎながら、 [〜#〜] php [〜#〜] の別のファイルに含まれているものとして使用する方法はありますか?

34
Martti Laine

使用する場合

define('APP_RAN'); 

それを含むファイルに入れて

if(!defined('APP_RAN')){ die(); }

または代わりに

defined('APP_RAN') or die();

(読みやすい)

インクルードされたファイルでは、直接アクセスすると死んでしまいます。


ただし、含まれているすべてのファイルをDocumentRootの上に配置することをお勧めします。

たとえば、インデックスページが

/my/server/domain/public_html

含まれているファイルをに入れる必要があります

/my/server/domain/
53
Tyler Carter

ファイルでグローバルコードを使用せず、関数とメソッドのみを使用してください。そうすれば、インクルードと直接使用を気にする必要がなくなります。

14
user187291

私の提案:

<?php
if (__FILE__ == $_SERVER['SCRIPT_FILENAME']) {
    header($_SERVER['SERVER_PROTOCOL'] . ' 404 Not Found');
    exit("<!DOCTYPE HTML PUBLIC \"-//IETF//DTD HTML 2.0//EN\">\r\n<html><head>\r\n<title>404 Not Found</title>\r\n</head><body>\r\n<h1>Not Found</h1>\r\n<p>The requested URL " . $_SERVER['SCRIPT_NAME'] . " was not found on this server.</p>\r\n</body></html>");
}
else {
   // your code
}
?>

1.)直接呼び出されたかどうかをチェックし、そうでない場合はエラーをスローします

2.)404標準のApacheエラーページを出力し(元の404ページと比較するか、単純にそのページを含める)、隠すことでセキュリティを強化します。

3.)else-partは、ファイルがライブ環境にアップロードされている間、部分的な実行を回避します(PHPは "?>"を待機しません)。インクルードされたファイルに1つの関数/ 1つのクラスしか含まれていない場合は、必要ありません。

14
mgutt
if (!defined('FLAG_FROM_A_PARENT'))
// Works in all scenarios but I personally dislike this

if (__FILE__ == get_included_files()[0])
// Doesn't work with PHP prepend unless calling [1] instead.

if (__FILE__ == $_SERVER['DOCUMENT_ROOT'] . $_SERVER['SCRIPT_FILENAME'])
// May break on Windows due to mixed DIRECTORY_SEPARATOR

if (basename(__FILE__) == basename($_SERVER['SCRIPT_FILENAME']))
// Doesn't work with files with the same basename but different paths

if (realpath(__FILE__) == realpath($_SERVER['DOCUMENT_ROOT'].$_SERVER['SCRIPT_NAME']))
// Seems to do the trick
11
tim

ファイルをWebルートの外に保存するだけです。

10
Erik

get_included_files 関数があります。あなたはそれを次のように使うことができます:

if ( empty(get_included_files()) ) die("Direct access forbidden");
6
moebius_eye
if (__FILE__ == $_SERVER['DOCUMENT_ROOT'].$_SERVER['PHP_SELF']){
  die("Direct access forbidden");
}

どこにいても動作します。 (不完全でありながら優れた解決策を指摘してくれた@ col-sharpnelに乾杯。)

6
moebius_eye

含まれているファイルの数を確認してください...

if(count(get_required_files()) < 2) { die(); }

または、2ではなく最低数はいくつあるべきか

2
HelpNeeder

Apacheでは、これは簡単です。htaccessに<Files>ディレクティブを追加して、Webブラウザからのアクセスを防止します。これはPHP includesには適用されません。また、ブラウザアクセスから複数のファイルを非表示にすることをお勧めします(ただし、通常はアクセスできないファイルをすべて配置しようとします)。ファイルを1つのディレクトリにまとめます)。

<Files="myprivatefile.php">
    deny from all
</Files>

別のWebサーバーでは、ファイルをドキュメントルートから隠すことができますが、場合によっては(スクリプトが厳密にopen_basedirされている場合など)、機能しません。

2
zneak

含まれていないときに表示されないようにしたい場合は、より自動化された方法があります。

if (basename(__FILE__) == basename($_SERVER['PHP_SELF'])) header("HTTP/1.0 404 Not Found");

このようにして、ファイル名などを変更した場合でも機能します。

1
ZeekDaGeek
if($argv[0] == basename(__FILE__))
    include_once('/path/to/file.php');
1
mechimdi

このスレッドには多くの良い答えがあります-これはまだ言及されていないものです。

含まれているPHPファイルには、拡張子にiを付けて名前を付けることができます(例:someincludedfile.phpiし、phpiファイルを提供しないようにApacheを設定します。出来上がり。

短所:

  • (!)Apacheの設定に大きく依存しているため(誰かがその行を無視すると脆弱になります)-そのような場合、ブラウザはPHPスクリプト全体をプレーンテキストで表示しますPHP(本当に悪い!)
  • 含まれているファイルの名前を変更するのは面倒な場合があります

長所:

  • インクルードするファイルとコードにないファイルを明確にする
  • ファイル階層を移動する必要はありません

個人的には、ファイルをドキュメントルートの外部のディレクトリに移動したいのですが、大規模なレガシーアプリケーションがある場合は、これを変更する方が早い可能性があります。

リンク: http://www.ducea.com/2006/07/21/Apache-tips-tricks-deny-access-to-certain-file-types/

1
Chris Middleton

Chacha102のソリューション を選びます。

さらに、質問のタイトルに「方法チェック」と書かれているので、を使用して変数を定義するには

// secret.php is the name of this file.
if($_SERVER["SCRIPT_FILENAME"]=='secret.php') die();
0
Daan

$_SERVER変数を使用したソリューションを拡張するために、以下は小さな.phpファイルであり、コメントには、Ubuntuで行ったbashテストのコピーがあります。重要なのは、これらの変数は、アクセスのタイプ、およびシンボリックリンクが使用されているかどうかに応じてかなり変化する可能性があるということです(また、以下のコードでは、echoステートメントの「?\>」をエスケープする必要があります。そうしないと、構文の色が壊れます。コードを試す場合はバックスラッシュを削除してください):

<?php

function report($label, $value) {
  printf ("%23s: %s\n", $label, $value);
}

report("DOCUMENT_ROOT.PHP_SELF",  $_SERVER['DOCUMENT_ROOT'].$_SERVER['PHP_SELF'] );
report("SCRIPT_FILENAME",         $_SERVER['SCRIPT_FILENAME'] );
report("__FILE__",                __FILE__ );
report("PHP_SAPI",                PHP_SAPI );

/*
# the test (bash):

home~$ mkdir /tmp/ptest
home~$ cd /tmp/ptest/
ptest$ ln -s /real/path/to/varcheck.php .
ptest$ echo '<? require_once "varcheck.php"; ?\>' > varcheckincl.php


# ... and in a separate terminal, run
# php (>5.4) cli server at same (/tmp/ptest) location:

ptest$ php-5.4.10 -S localhost:8000

# back to first terminal, the test - and output:

ptest$ php varcheck.php
 DOCUMENT_ROOT.PHP_SELF: varcheck.php
        SCRIPT_FILENAME: varcheck.php
               __FILE__: /real/path/to/varcheck.php
               PHP_SAPI: cli

ptest$ php -r 'require_once "varcheck.php";'
 DOCUMENT_ROOT.PHP_SELF: -
        SCRIPT_FILENAME:
               __FILE__: /real/path/to/varcheck.php
               PHP_SAPI: cli

ptest$ php varcheckincl.php
 DOCUMENT_ROOT.PHP_SELF: varcheckincl.php
        SCRIPT_FILENAME: varcheckincl.php
               __FILE__: /real/path/to/varcheck.php
               PHP_SAPI: cli

ptest$ wget http://localhost:8000/varcheck.php -q -O -
 DOCUMENT_ROOT.PHP_SELF: /tmp/ptest/varcheck.php
        SCRIPT_FILENAME: /tmp/ptest/varcheck.php
               __FILE__: /real/path/to/varcheck.php
               PHP_SAPI: cli-server

ptest$ wget http://localhost:8000/varcheckincl.php -q -O -
 DOCUMENT_ROOT.PHP_SELF: /tmp/ptest/varcheckincl.php
        SCRIPT_FILENAME: /tmp/ptest/varcheckincl.php
               __FILE__: /real/path/to/varcheck.php
               PHP_SAPI: cli-server
*/
?>
0
sdaau