2011-10-01 10 views
7

Ho un semplice script che determina l'indirizzo IP dell'utente:

function GetIp(){ 
     if (!empty($_SERVER['HTTP_CLIENT_IP'])) 
     //check ip from share internet 
     { 
     $ip=$_SERVER['HTTP_CLIENT_IP']; 
     } 
     elseif (!empty($_SERVER['HTTP_X_FORWARDED_FOR'])) 
     //to check ip is pass from proxy 
     { 
     $ip=$_SERVER['HTTP_X_FORWARDED_FOR']; 
     } 
     else 
     { 
     $ip=$_SERVER['REMOTE_ADDR']; 
     } 
     return $ip; 
} 

Ora in Rete da qualche parte ho visto una persona che utilizza questo script:

if (isset($_SERVER['HTTP_CLIENT_IP']) && $_SERVER['HTTP_CLIENT_IP'] != '') 
     $Ip = $_SERVER['HTTP_CLIENT_IP']; 
    elseif (isset($_SERVER['HTTP_X_FORWARDED_FOR']) && $_SERVER['HTTP_X_FORWARDED_FOR'] != '') 
     $Ip = $_SERVER['HTTP_X_FORWARDED_FOR']; 
    elseif (isset($_SERVER['REMOTE_ADDR']) && $_SERVER['REMOTE_ADDR'] != '') 
     $Ip = $_SERVER['REMOTE_ADDR']; 

Mi chiedevo se la mia applicazione è rotto .. Devo controllare se il valore di $_SERVER['HTTP_CLIENT_IP'], $_SERVER['HTTP_X_FORWARDED_FOR'] o $_SERVER['REMOTE_ADDR'] è vuoto? O in realtà non è necessario farlo?

+1

Qual è lo scopo di questo? È in qualche modo rilevante per la sicurezza? Perché se lo è, "REMOTE_ADDR" è l'unico che valga la pena. –

+0

Depends. Ricordo che alcune società di hosting sono là fuori che hanno un proxy di fronte ai loro server e inseriscono i proxy * local * IP che portano a 'REMOTE_ADDR' sempre come qualcosa di' 10.0.0.1' ... Quindi se si voleva ottenere l'IP dei client che dovevi usare con 'X_FORWARDED_FOR' – klaustopher

risposta

12

Se il motivo per cui si desidera scoprire l'indirizzo IP del client è davvero importante, rovinare tutto questo.

Qualsiasi di questi valori di intestazione può essere liberamente falsificato.

REMOTE_ADDR è l'unica informazione veramente affidabile, poiché viene trasmessa dal server Web che gestisce la richiesta. Può essere teoricamente falsified as well, ma è molto, molto più difficile dello spoofing di un valore di intestazione e una classe di attacco completamente diversa.

Esistono eccezioni in ambienti di hosting molto specifici per i proxy inversi. In questi casi, la persona che amministra quel proxy sarà in grado di dire quale valore dell'intestazione è necessario testare.

+0

Potresti elaborare le parole "liberamente spoofed". Intendi dire che un laico come me potrebbe spoofare un sito web che usa questo tipo di sceneggiatura? – Pacerier

+0

@Pacerier sì - vuol dire che quando faccio una richiesta al tuo sito web, potrei inviare lungo un'intestazione 'X_HTTP_FORWARDED_FOR' con qualsiasi valore (ad esempio l'indirizzo IP di qualcun altro). È facilmente fattibile usando curl o un plugin per il browser. In una configurazione normale, 'REMOTE_ADDR' è l'unico indirizzo IP affidabile che ci sia. Lo snippet di @ kemo tiene conto di ciò confidando i valori dell'header solo quando provengono da un proxy fidato –

+0

grazie per le informazioni! e questi ragazzi qui http://stackoverflow.com/questions/444966/working-with-ipv6-addresses-in-php nominano le funzioni come ** GetRealRemoteIp ** come se fosse * più forte * di semplicemente fare $ _SERVER [ "REMOTE_ADDR"] – Pacerier

1

Le due cose sono praticamente identiche. Nello script che hai trovato, l'autore sta semplicemente controllando se l'elemento nell'array è impostato prima di verificare che non sia vuoto.

Per quanto riguarda l'utilizzo della funzione empty() anziché del confronto, selezionare http://php.net/empty. Dato che hai a che fare con una variabile impostata dall'ambiente e non da un input dell'utente, non importa quale delle due opzioni scegli. Quindi, lo script dovrebbe essere perfettamente bene

+0

Voglio dire che sono consapevole che sta facendo un controllo vuoto, mi chiedo se è necessario fare una cosa del genere. In altre parole ... riuscirò mai a ottenere un risultato di lunghezza zero? – Pacerier

8

Da Kohanas' class Richiesta:

if (isset($_SERVER['HTTP_X_FORWARDED_FOR']) 
    AND isset($_SERVER['REMOTE_ADDR']) 
    AND in_array($_SERVER['REMOTE_ADDR'], Request::$trusted_proxies)) 
{ 
    // Use the forwarded IP address, typically set when the 
    // client is using a proxy server. 
    // Format: "X-Forwarded-For: client1, proxy1, proxy2" 
    $client_ips = explode(',', $_SERVER['HTTP_X_FORWARDED_FOR']); 

    Request::$client_ip = array_shift($client_ips); 

    unset($client_ips); 
} 
elseif (isset($_SERVER['HTTP_CLIENT_IP']) 
    AND isset($_SERVER['REMOTE_ADDR']) 
    AND in_array($_SERVER['REMOTE_ADDR'], Request::$trusted_proxies)) 
{ 
    // Use the forwarded IP address, typically set when the 
    // client is using a proxy server. 
    $client_ips = explode(',', $_SERVER['HTTP_CLIENT_IP']); 

    Request::$client_ip = array_shift($client_ips); 

    unset($client_ips); 
} 
elseif (isset($_SERVER['REMOTE_ADDR'])) 
{ 
    // The remote IP address 
    Request::$client_ip = $_SERVER['REMOTE_ADDR']; 
} 

Questo è più o meno buono come si arriva. Si prega di notare la matrice Request::$trusted_proxies e che la vostra variabile $ip è Request::$client_ip in questo caso.

7

Non controllare le intestazioni HTTP_* per l'IP del client a meno che non si sappia specificamente che l'applicazione è configurata dietro un proxy inverso. Affidarsi incondizionatamente ai valori di questi header consentirà agli utenti di falsificare il loro indirizzo IP.

L'unico campo $_SERVER contenente un valore affidabile è REMOTE_ADDR.

+0

Ic .. Avrei davvero ottenuto lo script qui http://stackoverflow.com/questions/444966/working-with-ipv6-addresses-in-php potresti spiegare perché tutti usano questo tipo di script di rilevamento IP e mettono in una funzione denominata * GetRealIp * se * ip reale * è memorizzato in $ _SERVER ["REMOTE_ADDR"]? – Pacerier

+1

Perché stanno scrivendo codice non sicuro. Guarda i commenti! – duskwuff

Problemi correlati