2011-10-01 11 views
7

Tengo un script sencillo que determina la dirección IP del usuario:

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

Ahora en la red algún lugar vi a alguien usando este 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']; 

Me preguntaba si mi aplicación se rompe .. ¿Debo verificar si el valor de $_SERVER['HTTP_CLIENT_IP'], $_SERVER['HTTP_X_FORWARDED_FOR'] o $_SERVER['REMOTE_ADDR'] está vacío? ¿O es realmente innecesario hacerlo?

+1

¿Cuál es el propósito de esto? ¿Es de alguna manera relevante para la seguridad? Porque si lo es, 'REMOTE_ADDR' es el único que vale la pena. –

+0

Depende. Recuerdo algunas compañías de hosting que tienen un proxy en frente de sus servidores y envían los proxies * local * IP que llevan a 'REMOTE_ADDR' siendo siempre algo así como' 10.0.0.1' ... Así que si querías obtener la IP de los clientes que tenía que ir con 'X_FORWARDED_FOR' – klaustopher

Respuesta

12

Si la razón por la que desea conocer la dirección IP del cliente es realmente importante, arruine todo esto.

Cualquier de estos valores de encabezado se puede falsificar libremente.

REMOTE_ADDR es la única información realmente confiable, ya que es transmitida a usted por su servidor web que está manejando la solicitud. Puede ser teóricamente falsified as well, pero eso es mucho, mucho más difícil que suplantar un valor de encabezado, y una clase de ataque completamente diferente.

Existen excepciones en entornos de alojamiento muy, muy específicos detrás de proxies inversos. En esos casos, la persona que administra ese proxy podrá decir qué valor de encabezado necesita probar.

+0

¿Podrían explicar las palabras "se burló libremente" ... ¿Quiere decir que un profano como yo podría falsificar un sitio web que usa este tipo de guión? – Pacerier

+0

@Pacerier yup: significa que cuando realizo una solicitud a su sitio web, podría enviar un encabezado 'X_HTTP_FORWARDED_FOR' con cualquier valor (por ejemplo, la dirección IP de otra persona). Eso es fácilmente factible usando curl o un plugin de navegador. En una configuración normal, 'REMOTE_ADDR' es la única dirección IP confiable que existe. El fragmento de @ kemo lo tiene en cuenta al confiar en los valores del encabezado solo cuando provienen de un proxy confiable. –

+0

¡gracias por la información! y estos tipos aquí http://stackoverflow.com/questions/444966/working-with-ipv6-addresses-in-php están nombrando las funciones como ** GetRealRemoteIp ** como si fuera * más fuerte * que simplemente haciendo $ _SERVER [ "REMOTE_ADDR"] – Pacerier

1

Las dos cosas son prácticamente idénticas .. En el script que encontraste, el autor solo está haciendo una comprobación si el elemento en la matriz se establece antes de comprobar que no está vacío.

Con respecto al uso de la función empty() en lugar de la comparación, marque http://php.net/empty. Como se trata de una variable establecida por el entorno y no por un usuario, no importa cuál de las dos opciones elija. Así que la secuencia de comandos debe estar perfectamente bien

+0

Quiero decir que soy consciente de que está haciendo un control vacío, me pregunto si es necesario hacer tal cosa. En otras palabras, ¿obtendré alguna vez un resultado de longitud cero? – Pacerier

8

de la clase Solicitud Kohanas':

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

Esto es casi tan bueno como se pone. Tenga en cuenta la matriz Request::$trusted_proxies y que su var $ip es Request::$client_ip en este caso.

7

No marque ningún encabezado HTTP_* para el IP del cliente a menos que sepa específicamente que su aplicación está configurada detrás de un proxy inverso. Confiar incondicionalmente en los valores de estos encabezados permitirá a los usuarios falsificar su dirección IP.

El único campo $_SERVER que contiene un valor confiable es REMOTE_ADDR.

+0

Ic .. De hecho, me dieron el guión aquí http://stackoverflow.com/questions/444966/working-with-ipv6-addresses-in-php ¿podría explicar por qué todos los que usan este tipo de IP detectan secuencias de comandos y ponen en una función llamada * GetRealIp * si * real ip * se almacena en $ _SERVER ["REMOTE_ADDR"]? – Pacerier

+1

Porque están escribiendo código inseguro. Mira los comentarios! – duskwuff

Cuestiones relacionadas