Comment puis-je détecter si l'utilisateur est sur localhost en PHP?

99

En d'autres termes, comment puis-je savoir si la personne qui utilise mon application Web se trouve sur le serveur sur lequel elle réside? Si je me souviens bien, PHPMyAdmin fait quelque chose comme ça pour des raisons de sécurité.

Richie Marquez
la source

Réponses:

177

Vous pouvez également utiliser $_SERVER['REMOTE_ADDR']pour quelle adresse IP du client qui fait la demande est donnée par le serveur Web.

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

if(!in_array($_SERVER['REMOTE_ADDR'], $whitelist)){
    // not valid
}
Mauris
la source
2
Ce qui rendrait cela plus facile à briser que l'usurpation de l'adresse IP. Vous devriez vraiment le changer.
Pekka
3
@ skcin7 peut être le paramètre de votre serveur. vérifie ça.
mauris
4
@Pekka 웃 vous pouvez simplement envoyer par exemple Host: 127.0.0.1et il serait rempli HTTP_HOST, donc ce n'est pas du tout une méthode fiable.
Dejan Marjanović
4
Ouais, c'est un mauvais conseil et dans sa forme actuelle et doit être modifié - ou rejeté.
Pekka
3
N'oubliez pas IPv6:$whitelist = array('127.0.0.1', '::1');
CrazyMax
26

En complément, en fonction ...

function isLocalhost($whitelist = ['127.0.0.1', '::1']) {
    return in_array($_SERVER['REMOTE_ADDR'], $whitelist);
}
Jens Törnell
la source
5
Comme bonne pratique, je recommanderais d'ajouter "else return false;" de sorte que la fonction renvoie toujours une valeur booléenne. Ou bien, supprimez simplement le "if" complètement et à la place "return in_array ($ _SERVER ['REMOTE_ADDR'], $ whitelist);"
Joe Irby
15

Les utilisateurs de systèmes d'exploitation plus récents (Win 7, 8) peuvent également trouver nécessaire d'inclure une adresse distante au format IPV6 dans leur tableau de liste blanche:

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

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

$_SERVER["REMOTE_ADDR"]devrait vous indiquer l'adresse IP de l'utilisateur. Il est cependant usurpable.

Consultez cette question sur les primes pour une discussion très détaillée.

Je pense que ce dont vous vous souvenez avec PHPMyAdmin est différent: de nombreux serveurs MySQL sont configurés de manière à ne pouvoir être accessibles qu'à partir de localhost pour des raisons de sécurité.

Pekka
la source
Il convient de noter que certains serveurs MySQL sont ainsi configurés en ne se liant pas à une interface publique. De même, si vous souhaitez restreindre une application PHP de la même manière, vous devriez envisager de la servir via une instance apache liée uniquement à une interface interne.
Frank Farmer
8

Je suis désolé mais toutes ces réponses me semblent terribles. Je suggérerais de reformuler la question parce que dans un sens, toutes les machines sont "localhost".

La question devrait être; Comment exécuter différents chemins de code en fonction de la machine sur laquelle il est exécuté.

À mon avis, le moyen le plus simple est de créer un fichier appelé DEVMACHINE ou ce que vous voulez vraiment, puis de vérifier simplement

file_exists ('DEVMACHINE')

N'oubliez pas d'exclure ce fichier lors du téléchargement vers l'environnement d'hébergement en direct!

Cette solution ne dépend pas de la configuration du réseau, elle ne peut pas être usurpée et permet de basculer facilement entre l'exécution de "live-code" et "dev-code".

Daniklad
la source
6

Il ne semble pas que vous devriez utiliser $_SERVER['HTTP_HOST'], car c'est la valeur de l'en-tête http, facilement simulée.

Vous pouvez utiliser $_SERVER["REMOTE_ADDR"]aussi, c'est la valeur la plus sûre, mais il est également possible de truquer. Il remote_addrs'agit de l'adresse à laquelle Apache renvoie le résultat.

Nicola
la source
REMOTE_ADDRIl est possible de faire semblant, cependant, si vous voulez le simuler en tant que 127.0.0.1ou ::1, cela nécessite de compromettre la machine, pour laquelle une usurpation REMOTE_ADDRest le moindre de vos soucis. Réponse pertinente - stackoverflow.com/a/5092951/3774582
Goose
1

Si vous souhaitez avoir une liste blanche / liste d'autorisation qui prend en charge les adresses IP statiques et les noms dynamiques .

Par exemple:

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

De cette façon, vous pouvez définir une liste de noms / IP qui pourront (à coup sûr) être détectés. Les noms dynamiques ajoutent plus de flexibilité pour accéder à partir de différents points.

Vous avez deux options communes ici, vous pouvez définir un nom dans votre fichier d'hôtes local ou vous pouvez simplement utiliser un fournisseur de noms dynamiques qui peut être trouvé n'importe où.

Cette fonction CACHES résulte du fait que gethostbyname est une fonction très lente.

Pour cela, j'ai implémenté cette fonction:

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

Pour une meilleure fiabilité, vous pouvez remplacer le $ _SERVER ['REMOTE_ADDR'] pour le get_ip_address () que @Pekka a mentionné dans son message comme "cette question de prime"

Heroselohim
la source
1
Je ne sais pas pourquoi quelqu'un attribue un score négatif à ma réponse alors qu'elle offre clairement une résolution de nom dynamique et d'autres non. La résolution DNS est lente, c'est pourquoi la mise en cache des résolutions est requise.
Heroselohim
1

Que diriez-vous de comparer $_SERVER['SERVER_ADDR'] === $_SERVER['REMOTE_ADDR']pour déterminer si le client est sur la même machine que le serveur?

Eugen Wesseloh
la source
$_SERVER['SERVER_ADDR']ne renvoie pas toujours de manière fiable l'adresse du serveur, par exemple si vous utilisez des équilibreurs de charge, il renvoie l'adresse IP de l'équilibreur de charge, je crois.
Mike W
-2

J'ai trouvé une réponse facile.

Parce que tous les lecteurs locaux ont C: ou D: ou F: ... etc.

Détectez simplement si le deuxième caractère est un:

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
la source