ユーザーがPHPのローカルホストにいるかどうかをどのように検出できますか?


99

つまり、自分のWebアプリケーションを使用しているユーザーが、それが常駐しているサーバー上にあるかどうかをどのように確認できますか?私の記憶が正しければ、PHPMyAdminはセキュリティ上の理由からこのようなことをします。

回答:


177

$_SERVER['REMOTE_ADDR']Webサーバーから要求されたクライアントのIPアドレスを使用することもできます。

$whitelist = array(
    '127.0.0.1',
    '::1'
);

if(!in_array($_SERVER['REMOTE_ADDR'], $whitelist)){
    // not valid
}

2
これにより、IPをスプーフィングするよりも簡単に解読できます。あなたは本当にそれを変更する必要があります。
Pekka

3
@ skcin7がサーバー設定である可能性があります。確認してください。
モーリス

4
@Pekka웃送信するだけで、たとえばHost: 127.0.0.1に入力されるHTTP_HOSTため、信頼できる方法ではありません。
DejanMarjanović2013年

4
ええ、これは悪いアドバイスであり、現在の形であり、編集するか、反対票を投じる必要があります。
Pekka 2013

3
IPv6を忘れないでください:$whitelist = array('127.0.0.1', '::1');
CrazyMax

26

補足として、機能として...

function isLocalhost($whitelist = ['127.0.0.1', '::1']) {
    return in_array($_SERVER['REMOTE_ADDR'], $whitelist);
}

5
「else return false;」を追加することをお勧めします。そのため、関数は常にブール値を返します。または、「if」を完全に削除して、代わりに「return in_array($ _SERVER ['REMOTE_ADDR']、$ whitelist);」を削除することもできます。
Joe Irby

15

新しいOSユーザー(Win 7、8)も、ホワイトリストアレイにIPV6形式のリモートアドレスを含める必要がある場合があります。

$whitelist = array('127.0.0.1', "::1");

if(!in_array($_SERVER['REMOTE_ADDR'], $whitelist)){
    // not valid
}

14

$_SERVER["REMOTE_ADDR"]ユーザーのIPを教えてください。ただし、なりすましです。

非常に詳細な議論については、この賞金問題をチェックしてください。

PHPMyAdminで覚えていることは何か違うと思います。多くのMySQLサーバーは、セキュリティ上の理由からlocalhostからのみアクセスできるように構成されています。


一部のMySQLサーバーは、パブリックインターフェイスにバインドしないように構成されていることに注意してください。同様に、同じ方法でPHPアプリケーションを制限したい場合は、内部インターフェースのみにバインドされたapacheインスタンスを介してアプリケーションを提供することを検討する必要があります。
Frank Farmer

8

申し訳ありませんが、これらの回答はすべてひどいものです。ある意味ではすべてのマシンが「localhost」なので、質問を言い換えることをお勧めします。

問題は次のとおりです。実行するマシンに応じて異なるコードパスを実行するにはどうすればよいですか。

私の意見では、最も簡単な方法は、DEVMACHINEまたは実際に必要なものと呼ばれるファイルを作成し、単純にチェックすることです

file_exists( 'DEVMACHINE')

ライブホスティング環境にアップロードするときは、このファイルを除外することを忘れないでください!

このソリューションはネットワーク構成に依存せず、なりすましができないため、実行中の「ライブコード」と「開発コード」を簡単に切り替えることができます。


6

これは$_SERVER['HTTP_HOST']httpヘッダーの値であり、簡単に偽造されるため、使用する必要はないようです。

あなたも使用$_SERVER["REMOTE_ADDR"]できます。これはより安全な値ですが、偽造することも可能です。これremote_addrは、Apacheが結果を返すアドレスです。


REMOTE_ADDR偽造することは可能ですが、127.0.0.1または として偽造したい場合は::1、マシンを危険にさらす必要がREMOTE_ADDRあります。関連する回答-stackoverflow.com/a/5092951/3774582
Goose

1

静的IP動的名をサポートするホワイトリスト/許可リストが必要な場合

例えば:

$whitelist = array("localhost", "127.0.0.1", "devel-pc.ds.com", "liveserver.com");
if (!isIPWhitelisted($whitelist)) die();

このようにして、(確実に)検出できる名前/ IPのリストを設定できます。動的な名前は、さまざまなポイントからアクセスするための柔軟性を高めます。

ここには2つの一般的なオプションがあります。ローカルのhostsファイルに名前を設定することも、どこにでもある動的な名前プロバイダーを1つだけ使用することもできます。

gethostbynameは非常に遅い関数であるため、この関数はCACHESになります。

この目的のために、私はこの関数を実装しました:

function isIPWhitelisted($whitelist = false)
{
    if ( isset($_SESSION) && isset($_SESSION['isipallowed']) )
        { return $_SESSION['isipallowed'];  }

    // This is the whitelist
    $ipchecklist = array("localhost", "127.0.0.1", "::1");
    if ($whitelist) $ipchecklist = $whitelist;

    $iplist = false;
    $isipallowed = false;

    $filename = "resolved-ip-list.txt";
    $filename = substr(md5($filename), 0, 8)."_".$filename; // Just a spoon of security or just remove this line

    if (file_exists($filename))
    {
        // If cache file has less than 1 day old use it
        if (time() - filemtime($filename) <= 60*60*24*1)
            $iplist = explode(";", file_get_contents($filename)); // Read cached resolved ips
    }

    // If file was not loaded or found -> generate ip list
    if (!$iplist)
    {
        $iplist = array(); $c=0;
        foreach ( $ipchecklist as $k => $iptoresolve )
        {
            // gethostbyname: It's a VERY SLOW function. We really need to cache the resolved ip list
            $ip = gethostbyname($iptoresolve);
            if ($ip != "") $iplist[$c] = $ip;
            $c++;
        }

        file_put_contents($filename, implode(";", $iplist));
    }

    if (in_array($_SERVER['REMOTE_ADDR'], $iplist)) // Check if the client ip is allowed
        $isipallowed = true;

    if (isset($_SESSION)) $_SESSION['isipallowed'] = $isipallowed;

    return $isipallowed;
}

信頼性を高めるために、@ Pekkaが彼の投稿「この賞金の質問」と述べたget_ip_address()$ _SERVER ['REMOTE_ADDR']を置き換えることができます


1
なぜ誰かが私の回答に否定的なスコアを設定したのかはわかりませんが、動的な名前解決は提供されますが、他の人はそうではありません。DNS解決が遅いため、キャッシング解決が必要です。
ヒーローセロヒム2016年

1

比較$_SERVER['SERVER_ADDR'] === $_SERVER['REMOTE_ADDR']して、クライアントがサーバーと同じマシン上にあるかどうかを判断しますか?


$_SERVER['SERVER_ADDR']たとえば、ロードバランサーを使用している場合、サーバーのアドレスが確実に返されるとは限りません。ロードバランサーのIPアドレスが返されると思います。
マイクW

-2

簡単な答えを見つけました。

すべてのローカルドライブにC:またはD:またはF:...などがあるため

2番目の文字が:かどうかを検出するだけです。

if ( substr_compare(getcwd(),":",1,1) == 0)
{
echo '<script type="text/javascript">alert(" The working dir is at the local computer ")</script>';
    $client_or_server = 'client';
}
else
{
echo '<script type="text/javascript">alert(" The working dir is at the server ")</script>';
    $client_or_server = 'server';
}
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.