Wie kann ich feststellen, ob sich der Benutzer in PHP auf localhost befindet?

99

Mit anderen Worten, wie kann ich feststellen, ob sich die Person, die meine Webanwendung verwendet, auf dem Server befindet, auf dem sie sich befindet? Wenn ich mich richtig erinnere, macht PHPMyAdmin aus Sicherheitsgründen so etwas.

Richie Marquez
quelle

Antworten:

177

Sie können auch verwenden, $_SERVER['REMOTE_ADDR']für welche IP-Adresse der anfordernde Client der Webserver angegeben wird.

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

if(!in_array($_SERVER['REMOTE_ADDR'], $whitelist)){
    // not valid
}
Mauris
quelle
2
Das würde es tatsächlich einfacher machen, dies zu brechen, als die IP zu fälschen. Du solltest es wirklich ändern.
Pekka
3
@ skcin7 könnte Ihre Servereinstellung sein. prüfen Sie.
Mauris
4
@ Pekka 웃 Sie können nur zB senden Host: 127.0.0.1und es würde ausgefüllt HTTP_HOST, so ist es überhaupt keine zuverlässige Methode.
Dejan Marjanović
4
Ja, das ist ein schlechter Rat und in seiner aktuellen Form und muss bearbeitet - oder herabgestimmt werden.
Pekka
3
Vergessen Sie nicht IPv6:$whitelist = array('127.0.0.1', '::1');
CrazyMax
26

Als Ergänzung, als Funktion ...

function isLocalhost($whitelist = ['127.0.0.1', '::1']) {
    return in_array($_SERVER['REMOTE_ADDR'], $whitelist);
}
Jens Törnell
quelle
5
Als gute Praxis würde ich empfehlen, "else return false" hinzuzufügen. so dass die Funktion immer einen booleschen Wert zurückgibt. Oder entfernen Sie alternativ einfach das "if" vollständig und stattdessen "return in_array ($ _SERVER ['REMOTE_ADDR'], $ whitelist)".
Joe Irby
15

Neuere Betriebssystembenutzer (Win 7, 8) müssen möglicherweise auch eine Remote-Adresse im IPV6-Format in ihr Whitelist-Array aufnehmen:

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

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

$_SERVER["REMOTE_ADDR"]sollte Ihnen die IP des Benutzers mitteilen. Es ist jedoch fälschbar.

Überprüfen Sie diese Kopfgeldfrage für eine sehr detaillierte Diskussion.

Ich denke, was Sie mit PHPMyAdmin in Erinnerung behalten, ist etwas anderes: Viele MySQL-Server sind so konfiguriert, dass aus Sicherheitsgründen nur von localhost aus auf sie zugegriffen werden kann.

Pekka
quelle
Es ist erwähnenswert, dass einige MySQL-Server so konfiguriert sind, dass sie nicht an eine öffentliche Schnittstelle gebunden sind. Wenn Sie eine PHP-Anwendung auf die gleiche Weise einschränken möchten, sollten Sie in Betracht ziehen, sie über eine Apache-Instanz bereitzustellen, die nur an eine interne Schnittstelle gebunden ist.
Frank Farmer
8

Es tut mir leid, aber all diese Antworten scheinen mir schrecklich. Ich würde vorschlagen, die Frage neu zu formulieren, da in gewissem Sinne alle Maschinen "localhost" sind.

Die Frage sollte sein; Wie führe ich verschiedene Codepfade aus, je nachdem auf welchem ​​Computer sie ausgeführt werden?

Meiner Meinung nach ist es am einfachsten, eine Datei namens DEVMACHINE oder was auch immer Sie wirklich wollen zu erstellen und dann einfach zu überprüfen

file_exists ('DEVMACHINE')

Denken Sie daran, diese Datei beim Hochladen in die Live-Hosting-Umgebung auszuschließen!

Diese Lösung hängt nicht von der Netzwerkkonfiguration ab, kann nicht gefälscht werden und erleichtert das Umschalten zwischen "Live-Code" und "Dev-Code".

Daniklad
quelle
6

Es scheint nicht, dass Sie verwenden sollten $_SERVER['HTTP_HOST'], da dies der Wert im http-Header ist, der leicht gefälscht werden kann.

Sie können auch verwenden $_SERVER["REMOTE_ADDR"], dies ist der sicherere Wert, aber es ist auch möglich zu fälschen. Dies remote_addrist die Adresse, an die Apache das Ergebnis zurückgibt.

nicola
quelle
REMOTE_ADDREs ist jedoch möglich zu fälschen, wenn Sie es als 127.0.0.1oder fälschen möchten ::1, was eine Kompromittierung der Maschine erfordert, bei der eine Fälschung REMOTE_ADDRdie geringste Ihrer Sorgen ist. Relevante Antwort - stackoverflow.com/a/5092951/3774582
Goose
1

Wenn Sie eine Whitelist / Zulassungsliste haben möchten , die statische IPs und dynamische Namen unterstützt .

Beispielsweise:

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

Auf diese Weise können Sie eine Liste von Namen / IPs festlegen , die (sicher) erkannt werden können. Dynamische Namen bieten mehr Flexibilität für den Zugriff von verschiedenen Punkten aus.

Sie haben hier zwei allgemeine Optionen: Sie können einen Namen in Ihrer lokalen Hosts-Datei festlegen oder nur einen Anbieter für dynamische Namen verwenden , der überall zu finden ist.

Diese Funktion CACHES ergibt sich, weil gethostbyname eine sehr langsame Funktion ist.

Für diesen Schüler habe ich folgende Funktion implementiert:

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;
}

Für eine bessere Zuverlässigkeit können Sie $ _SERVER ['REMOTE_ADDR'] für die get_ip_address () ersetzen, die @Pekka in seinem Beitrag als "diese Kopfgeldfrage" erwähnt hat.

Heroselohim
quelle
1
Ich weiß nicht, warum jemand meine Antwort negativ bewertet hat, obwohl sie eindeutig eine dynamische Namensauflösung bietet und andere nicht. Die DNS-Auflösung ist langsam, daher sind Caching-Auflösungen erforderlich.
Heroselohim
1

Wie wäre es mit einem Vergleich, $_SERVER['SERVER_ADDR'] === $_SERVER['REMOTE_ADDR']um festzustellen, ob sich der Client auf demselben Computer wie der Server befindet?

Eugen Wesseloh
quelle
$_SERVER['SERVER_ADDR']Gibt die Serveradresse nicht immer zuverlässig zurück, z. B. wenn Load Balancer verwendet werden, wird die IP-Adresse des Load Balancers zurückgegeben, glaube ich.
Mike W
-2

Ich fand eine einfache Antwort.

Weil alle lokalen Laufwerke C: oder D: oder F: ... usw. haben.

Erkennen Sie einfach, ob das zweite Zeichen ein:

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';
}
Scoobeedo Cool
quelle