studio reales proyectos programacion libro introducción incluye herramientas fundamentos fuente español código con avanzado aplicaciones php ip-address

php - reales - libro de android studio en español pdf



¿Cuál es la forma más precisa de recuperar la dirección IP correcta de un usuario en PHP? (16)

Aún así, sin embargo, obtener la dirección IP real de un usuario no será confiable. Todo lo que deben hacer es usar un servidor proxy anónimo (uno que no respete los encabezados de http_x_forwarded_for, http_forwarded, etc.) y todo lo que obtiene es la dirección IP de su servidor proxy.

Luego puede ver si hay una lista de direcciones IP del servidor proxy que son anónimas, pero no hay forma de asegurarse de que sea 100% precisa y que lo mejor que puede hacer es hacerle saber que es un servidor proxy. Y si alguien está siendo listo, pueden falsificar los encabezados para los reenvíos HTTP.

Digamos que no me gusta la universidad local. Averiguo qué direcciones IP registraron, y hago que su dirección IP sea prohibida en su sitio haciendo cosas malas, porque entiendo que respeta los reenvíos HTTP. La lista es interminable.

Luego hay, como lo has adivinado, direcciones IP internas, como la red de universidades que mencioné antes. Mucho uso un formato 10.xxx. Entonces, todo lo que sabría es que se reenvió para una red compartida.

Entonces no voy a empezar mucho con eso, pero las direcciones IP dinámicas ya son el camino de banda ancha. Asi que. Incluso si obtiene una dirección IP de usuario, espere que cambie en 2 a 3 meses, como máximo.

Sé que hay una gran cantidad de encabezados de variables $ _SERVER disponibles para la recuperación de direcciones IP. Me preguntaba si existe un consenso general sobre cómo recuperar con mayor precisión la dirección IP real de un usuario (sabiendo que ningún método es perfecto) usando dichas variables

Pasé un tiempo tratando de encontrar una solución en profundidad y encontré el siguiente código basado en varias fuentes. Me encantaría que alguien pudiera hacer agujeros en la respuesta o arrojar algo de luz sobre algo que quizás sea más preciso.

edición incluye optimizaciones de @Alix

/** * Retrieves the best guess of the client''s actual IP address. * Takes into account numerous HTTP proxy headers due to variations * in how different ISPs handle IP addresses in headers between hops. */ public function get_ip_address() { // Check for shared internet/ISP IP if (!empty($_SERVER[''HTTP_CLIENT_IP'']) && $this->validate_ip($_SERVER[''HTTP_CLIENT_IP''])) return $_SERVER[''HTTP_CLIENT_IP'']; // Check for IPs passing through proxies if (!empty($_SERVER[''HTTP_X_FORWARDED_FOR''])) { // Check if multiple IP addresses exist in var $iplist = explode('','', $_SERVER[''HTTP_X_FORWARDED_FOR'']); foreach ($iplist as $ip) { if ($this->validate_ip($ip)) return $ip; } } } if (!empty($_SERVER[''HTTP_X_FORWARDED'']) && $this->validate_ip($_SERVER[''HTTP_X_FORWARDED''])) return $_SERVER[''HTTP_X_FORWARDED'']; if (!empty($_SERVER[''HTTP_X_CLUSTER_CLIENT_IP'']) && $this->validate_ip($_SERVER[''HTTP_X_CLUSTER_CLIENT_IP''])) return $_SERVER[''HTTP_X_CLUSTER_CLIENT_IP'']; if (!empty($_SERVER[''HTTP_FORWARDED_FOR'']) && $this->validate_ip($_SERVER[''HTTP_FORWARDED_FOR''])) return $_SERVER[''HTTP_FORWARDED_FOR'']; if (!empty($_SERVER[''HTTP_FORWARDED'']) && $this->validate_ip($_SERVER[''HTTP_FORWARDED''])) return $_SERVER[''HTTP_FORWARDED'']; // Return unreliable IP address since all else failed return $_SERVER[''REMOTE_ADDR'']; } /** * Ensures an IP address is both a valid IP address and does not fall within * a private network range. * * @access public * @param string $ip */ public function validate_ip($ip) { if (filter_var($ip, FILTER_VALIDATE_IP, FILTER_FLAG_IPV4 | FILTER_FLAG_IPV6 | FILTER_FLAG_NO_PRIV_RANGE | FILTER_FLAG_NO_RES_RANGE) === false) return false; self::$ip = $ip; return true; }

Palabras de advertencia (actualización)

REMOTE_ADDR aún representa la fuente más confiable de una dirección IP. Las otras variables $_SERVER mencionadas aquí pueden ser falsificadas por un cliente remoto muy fácilmente. El propósito de esta solución es intentar determinar la dirección IP de un cliente sentado detrás de un proxy. Para sus propósitos generales, puede considerar usar esto en combinación con la dirección IP devuelta directamente desde $_SERVER[''REMOTE_ADDR''] y almacenar ambos.

Para el 99,9% de los usuarios, esta solución se adaptará perfectamente a sus necesidades. No lo protegerá del 0,1% de los usuarios malintencionados que intentan abusar de su sistema inyectando sus propios encabezados de solicitud. Si confiar en direcciones IP para algo de misión crítica, recurra a REMOTE_ADDR y no se moleste en atender a quienes están detrás de un proxy.


Aquí hay una versión modificada si usa los servicios de la capa de almacenamiento en caché de CloudFlare

function getIP() { $fields = array(''HTTP_X_FORWARDED_FOR'', ''REMOTE_ADDR'', ''HTTP_CF_CONNECTING_IP'', ''HTTP_X_CLUSTER_CLIENT_IP''); foreach($fields as $f) { $tries = $_SERVER[$f]; if (empty($tries)) continue; $tries = explode('','',$tries); foreach($tries as $try) { $r = filter_var($try, FILTER_VALIDATE_IP, FILTER_FLAG_IPV4 | FILTER_FLAG_NO_PRIV_RANGE | FILTER_FLAG_NO_RES_RANGE); if ($r !== false) { return $try; } } } return false; }


Básicamente, mi respuesta es solo una versión pulida, completamente validada y completamente empaquetada de la respuesta de @AlixAxel:

<?php /* Get the ''best known'' client IP. */ if (!function_exists(''getClientIP'')) { function getClientIP() { if (isset($_SERVER["HTTP_CF_CONNECTING_IP"])) { $_SERVER[''REMOTE_ADDR''] = $_SERVER["HTTP_CF_CONNECTING_IP"]; }; foreach (array(''HTTP_CLIENT_IP'', ''HTTP_X_FORWARDED_FOR'', ''HTTP_X_FORWARDED'', ''HTTP_X_CLUSTER_CLIENT_IP'', ''HTTP_FORWARDED_FOR'', ''HTTP_FORWARDED'', ''REMOTE_ADDR'') as $key) { if (array_key_exists($key, $_SERVER)) { foreach (explode('','', $_SERVER[$key]) as $ip) { $ip = trim($ip); if (filter_var($ip, FILTER_VALIDATE_IP, FILTER_FLAG_NO_PRIV_RANGE | FILTER_FLAG_NO_RES_RANGE) !== false) { return $ip; }; }; }; }; return false; }; }; $best_known_ip = getClientIP(); if(!empty($best_known_ip)) { $ip = $clients_ip = $client_ip = $client_IP = $best_known_ip; } else { $ip = $clients_ip = $client_ip = $client_IP = $best_known_ip = ''''; }; ?>

Cambios:

  • Simplifica el nombre de la función (con el estilo de formato ''camelCase'').

  • Incluye una verificación para asegurarse de que la función no esté declarada en otra parte de su código.

  • Tiene en cuenta la compatibilidad ''CloudFlare''.

  • Inicializa varios nombres de variable "relacionados con IP" en el valor devuelto, de la función ''getClientIP''.

  • Asegura que si la función no devuelve una dirección IP válida, todas las variables se configuran en una cadena vacía, en lugar de null .

  • Es sólo (45) líneas de código.


Como alguien dijo anteriormente, la clave aquí es por qué razón desea almacenar los ips del usuario.

Daré un ejemplo de un sistema de registro en el que trabajo y, por supuesto, la solución para contribuir con algo en esta vieja discusión que aparece frecuentemente en mis búsquedas.

Muchas bibliotecas de registro de php usan ip para acelerar / bloquear intentos fallidos basados ​​en la ip del usuario. Considere esta tabla:

-- mysql DROP TABLE IF EXISTS `attempts`; CREATE TABLE `attempts` ( `id` int(11) NOT NULL AUTO_INCREMENT, `ip` varchar(39) NOT NULL, /*<<=====*/ `expiredate` datetime NOT NULL, PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8; -- sqlite ...

Luego, cuando un usuario intenta iniciar sesión o cualquier cosa relacionada con el servicio como un restablecimiento de contraseña, se llama a una función desde el principio:

public function isBlocked() { /* * used one of the above methods to capture user''s ip!!! */ $ip = $this->ip; // delete attempts from this ip with ''expiredate'' in the past $this->deleteAttempts($ip, false); $query = $this->dbh->prepare("SELECT count(*) FROM {$this->token->get(''table_attempts'')} WHERE ip = ?"); $query->execute(array($ip)); $attempts = $query->fetchColumn(); if ($attempts < intval($this->token->get(''attempts_before_verify''))) { return "allow"; } if ($attempts < intval($this->token->get(''attempts_before_ban''))) { return "captcha"; } return "block"; }

Digamos, por ejemplo, $this->token->get(''attempts_before_ban'') === 10 y 2 usuarios vienen por los mismos ips que es el caso en los códigos anteriores donde los encabezados pueden ser falsificados , luego, después de 5 intentos, ambos están prohibidos ! Lo peor es que, si todos provienen del mismo proxy, solo se registrarán los primeros 10 usuarios y se prohibirá el resto.

La crítica aquí es que necesitamos un índice único en los attempts mesa y podemos obtenerlo de una combinación como:

`ip` varchar(39) NOT NULL, `jwt_load varchar(100) NOT NULL

donde jwt_load proviene de una cookie http que sigue la tecnología de token web json donde almacenamos solo la carga útil cifrada que debe contener un valor arbitrario / único para cada usuario. Por supuesto, la solicitud debe modificarse a: "SELECT count(*) FROM {$this->token->get(''table_attempts'')} WHERE ip = ? AND jwt_load = ?" y la clase también debe iniciar un private $jwt .


De la clase de Solicitud de Symfony https://github.com/symfony/symfony/blob/1bd125ec4a01220878b3dbc3ec3156b073996af9/src/Symfony/Component/HttpFoundation/Request.php

const HEADER_FORWARDED = ''forwarded''; const HEADER_CLIENT_IP = ''client_ip''; const HEADER_CLIENT_HOST = ''client_host''; const HEADER_CLIENT_PROTO = ''client_proto''; const HEADER_CLIENT_PORT = ''client_port''; /** * Names for headers that can be trusted when * using trusted proxies. * * The FORWARDED header is the standard as of rfc7239. * * The other headers are non-standard, but widely used * by popular reverse proxies (like Apache mod_proxy or Amazon EC2). */ protected static $trustedHeaders = array( self::HEADER_FORWARDED => ''FORWARDED'', self::HEADER_CLIENT_IP => ''X_FORWARDED_FOR'', self::HEADER_CLIENT_HOST => ''X_FORWARDED_HOST'', self::HEADER_CLIENT_PROTO => ''X_FORWARDED_PROTO'', self::HEADER_CLIENT_PORT => ''X_FORWARDED_PORT'', ); /** * Returns the client IP addresses. * * In the returned array the most trusted IP address is first, and the * least trusted one last. The "real" client IP address is the last one, * but this is also the least trusted one. Trusted proxies are stripped. * * Use this method carefully; you should use getClientIp() instead. * * @return array The client IP addresses * * @see getClientIp() */ public function getClientIps() { $clientIps = array(); $ip = $this->server->get(''REMOTE_ADDR''); if (!$this->isFromTrustedProxy()) { return array($ip); } if (self::$trustedHeaders[self::HEADER_FORWARDED] && $this->headers->has(self::$trustedHeaders[self::HEADER_FORWARDED])) { $forwardedHeader = $this->headers->get(self::$trustedHeaders[self::HEADER_FORWARDED]); preg_match_all(''{(for)=("?/[?)([a-z0-9/.:_/-/]*)}'', $forwardedHeader, $matches); $clientIps = $matches[3]; } elseif (self::$trustedHeaders[self::HEADER_CLIENT_IP] && $this->headers->has(self::$trustedHeaders[self::HEADER_CLIENT_IP])) { $clientIps = array_map(''trim'', explode('','', $this->headers->get(self::$trustedHeaders[self::HEADER_CLIENT_IP]))); } $clientIps[] = $ip; // Complete the IP chain with the IP the request actually came from $firstTrustedIp = null; foreach ($clientIps as $key => $clientIp) { // Remove port (unfortunately, it does happen) if (preg_match(''{((?:/d+/.){3}/d+)/:/d+}'', $clientIp, $match)) { $clientIps[$key] = $clientIp = $match[1]; } if (!filter_var($clientIp, FILTER_VALIDATE_IP)) { unset($clientIps[$key]); } if (IpUtils::checkIp($clientIp, self::$trustedProxies)) { unset($clientIps[$key]); // Fallback to this when the client IP falls into the range of trusted proxies if (null === $firstTrustedIp) { $firstTrustedIp = $clientIp; } } } // Now the IP chain contains only untrusted proxies and the client IP return $clientIps ? array_reverse($clientIps) : array($firstTrustedIp); }


Gracias por esto, muy útil.

Sería de gran ayuda si el código fuera sintácticamente correcto. Tal como está, hay demasiados alrededor de la línea 20. Lo cual me temo que significa que en realidad nadie lo intentó.

Puede que esté loco, pero después de intentarlo en algunas direcciones válidas e inválidas, la única versión de validate_ip () que funcionó fue la siguiente:

public function validate_ip($ip) { if (filter_var($ip, FILTER_VALIDATE_IP, FILTER_FLAG_NO_PRIV_RANGE) === false) return false; if (filter_var($ip, FILTER_VALIDATE_IP, FILTER_FLAG_NO_RES_RANGE) === false) return false; if (filter_var($ip, FILTER_VALIDATE_IP, FILTER_FLAG_IPV4) === false && filter_var($ip, FILTER_VALIDATE_IP, FILTER_FLAG_IPV6) === false) return false; return true; }


La pregunta más grande es con qué propósito?

Su código es casi tan completo como podría ser, pero veo que si ve lo que parece ser un encabezado agregado por proxy, usa ese INSTEAD del CLIENT_IP, sin embargo, si desea esta información para fines de auditoría, tenga cuidado: es muy fácil. falsificar.

Ciertamente, nunca debe usar direcciones IP para ningún tipo de autenticación, incluso estas pueden ser falsificadas.

Puede obtener una mejor medición de la dirección IP del cliente al desplegar un applet flash o java que se conecta de nuevo al servidor a través de un puerto no http (que por lo tanto revelaría proxies transparentes o casos donde los encabezados inyectados por proxy son falsos, pero tenga en cuenta que, cuando el cliente SOLO puede conectarse a través de un proxy web o el puerto de salida está bloqueado, no habrá conexión desde el applet.

DO.


Me doy cuenta de que hay respuestas mucho mejores y más concisas más arriba, y esto no es una función ni el script más elegante. En nuestro caso, tuvimos que generar tanto el spoofable x_forwarded_for como el remote_addr más confiable en un conmutador simplista por voz. Necesitaba permitir espacios en blanco para inyectar en otras funciones if-none o if-singular (en lugar de simplemente devolver la función preformateada). Necesitaba una var "on o off" con etiquetas personalizadas por interruptor para la configuración de la plataforma. También necesitaba una forma para que $ ip sea dinámico dependiendo de la solicitud para que tomara la forma de forwarded_for.

Además, no vi ninguna dirección de dirección isset () vs! Empty (): es posible no ingresar nada para x_forwarded_for, pero aún así desencadenar la verdad de isset () que da como resultado una var. En blanco, una forma de evitarlo es usar && y combinar ambas condiciones. Tenga en cuenta que puede falsificar palabras como "PWNED" como x_forwarded_for, así que asegúrese de esterilizar a una sintaxis de IP real si su salida está en algún lugar protegido o en DB.

Además, también puedes probar usando google translate si necesitas un multi-proxy para ver la matriz en x_forwarder_for. Si desea falsificar los encabezados para probar, vea esto en la extensión Chrome Client Header Spoof . Esto se establecerá de forma predeterminada en solo remote_addr estándar mientras esté detrás de un proxy.

No sé en qué caso remote_addr podría estar vacío, pero existe como alternativa, por si acaso.

// proxybuster - attempts to un-hide originating IP if [reverse]proxy provides methods to do so $enableProxyBust = true; if (($enableProxyBust == true) && (isset($_SERVER[''REMOTE_ADDR''])) && (isset($_SERVER[''HTTP_X_FORWARDED_FOR''])) && (!empty($_SERVER[''HTTP_X_FORWARDED_FOR'']))) { $ip = end(array_values(array_filter(explode('','',$_SERVER[''HTTP_X_FORWARDED_FOR''])))); $ipProxy = $_SERVER[''REMOTE_ADDR'']; $ipProxy_label = '' behind proxy ''; } elseif (($enableProxyBust == true) && (isset($_SERVER[''REMOTE_ADDR'']))) { $ip = $_SERVER[''REMOTE_ADDR'']; $ipProxy = ''''; $ipProxy_label = '' no proxy ''; } elseif (($enableProxyBust == false) && (isset($_SERVER[''REMOTE_ADDR'']))) { $ip = $_SERVER[''REMOTE_ADDR'']; $ipProxy = ''''; $ipProxy_label = ''''; } else { $ip = ''''; $ipProxy = ''''; $ipProxy_label = ''''; }

Para hacer que estos sean dinámicos para su uso en la (s) función (es) o consulta / eco / vistas a continuación, digamos para generación de informes o informes de errores, use globals o simplemente haga eco en el lugar que desee sin hacer un montón de otras condiciones o la salida de esquema estático funciones

function fooNow() { global $ip, $ipProxy, $ipProxy_label; // begin this actions such as log, error, query, or report }

Gracias por todos sus grandes pensamientos. Por favor, avíseme si esto podría ser mejor, aún un poco nuevo para estos encabezados :)


Me pregunto si tal vez debería iterar sobre el HTTP_X_FORWARDED_FOR explotado en orden inverso, ya que mi experiencia ha sido que la dirección IP del usuario termina al final de la lista separada por comas, por lo que a partir del inicio del encabezado, es más probable que obtenga la dirección IP de uno de los proxies devueltos, lo que potencialmente podría permitir el secuestro de sesión ya que muchos usuarios pueden acceder a través de ese proxy.


Se me ocurrió esta función que no solo devuelve la dirección IP sino una matriz con información de IP.

// Example usage: $info = ip_info(); if ( $info->proxy ) { echo ''Your IP is '' . $info->ip; } else { echo ''Your IP is '' . $info->ip . '' and your proxy is '' . $info->proxy_ip; }

Aquí está la función:

/** * Retrieves the best guess of the client''s actual IP address. * Takes into account numerous HTTP proxy headers due to variations * in how different ISPs handle IP addresses in headers between hops. * * @since 1.1.3 * * @return object { * IP Address details * * string $ip The users IP address (might be spoofed, if $proxy is true) * bool $proxy True, if a proxy was detected * string $proxy_id The proxy-server IP address * } */ function ip_info() { $result = (object) array( ''ip'' => $_SERVER[''REMOTE_ADDR''], ''proxy'' => false, ''proxy_ip'' => '''', ); /* * This code tries to bypass a proxy and get the actual IP address of * the visitor behind the proxy. * Warning: These values might be spoofed! */ $ip_fields = array( ''HTTP_CLIENT_IP'', ''HTTP_X_FORWARDED_FOR'', ''HTTP_X_FORWARDED'', ''HTTP_X_CLUSTER_CLIENT_IP'', ''HTTP_FORWARDED_FOR'', ''HTTP_FORWARDED'', ''REMOTE_ADDR'', ); foreach ( $ip_fields as $key ) { if ( array_key_exists( $key, $_SERVER ) === true ) { foreach ( explode( '','', $_SERVER[$key] ) as $ip ) { $ip = trim( $ip ); if ( filter_var( $ip, FILTER_VALIDATE_IP, FILTER_FLAG_NO_PRIV_RANGE | FILTER_FLAG_NO_RES_RANGE ) !== false ) { $forwarded = $ip; break 2; } } } } // If we found a different IP address then REMOTE_ADDR then it''s a proxy! if ( $forwarded != $result->ip ) { $result->proxy = true; $result->proxy_ip = $result->ip; $result->ip = $forwarded; } return $result; }


Solo otra manera limpia:

function validateIp($var_ip){ $ip = trim($var_ip); return (!empty($ip) && $ip != ''::1'' && $ip != ''127.0.0.1'' && filter_var($ip, FILTER_VALIDATE_IP, FILTER_FLAG_NO_PRIV_RANGE | FILTER_FLAG_NO_RES_RANGE) !== false) ? $ip : false; } function getClientIp() { $ip = @$this->validateIp($_SERVER[''HTTP_CLIENT_IP'']) ?: @$this->validateIp($_SERVER[''HTTP_X_FORWARDED_FOR'']) ?: @$this->validateIp($_SERVER[''HTTP_X_FORWARDED'']) ?: @$this->validateIp($_SERVER[''HTTP_FORWARDED_FOR'']) ?: @$this->validateIp($_SERVER[''HTTP_FORWARDED'']) ?: @$this->validateIp($_SERVER[''REMOTE_ADDR'']) ?: ''LOCAL OR UNKNOWN ACCESS''; return $ip; }


Solo una versión VB.NET de la respuesta:

Private Function GetRequestIpAddress() As IPAddress Dim serverVariables = HttpContext.Current.Request.ServerVariables Dim headersKeysToCheck = {"HTTP_CLIENT_IP", _ "HTTP_X_FORWARDED_FOR", _ "HTTP_X_FORWARDED", _ "HTTP_X_CLUSTER_CLIENT_IP", _ "HTTP_FORWARDED_FOR", _ "HTTP_FORWARDED", _ "REMOTE_ADDR"} For Each thisHeaderKey In headersKeysToCheck Dim thisValue = serverVariables.Item(thisHeaderKey) If thisValue IsNot Nothing Then Dim validAddress As IPAddress = Nothing If IPAddress.TryParse(thisValue, validAddress) Then Return validAddress End If End If Next Return Nothing End Function


Usamos:

/** * Get the customer''s IP address. * * @return string */ public function getIpAddress() { if (!empty($_SERVER[''HTTP_CLIENT_IP''])) { return $_SERVER[''HTTP_CLIENT_IP'']; } else if (!empty($_SERVER[''HTTP_X_FORWARDED_FOR''])) { $ips = explode('','', $_SERVER[''HTTP_X_FORWARDED_FOR'']); return trim($ips[count($ips) - 1]); } else { return $_SERVER[''REMOTE_ADDR'']; } }

La explosión en HTTP_X_FORWARDED_FOR se debe a problemas extraños que detectamos direcciones IP cuando se usó Squid .


Usted prácticamente respondió su propia pregunta! :)

function getRealIpAddr() { if(!empty($_SERVER[''HTTP_CLIENT_IP''])) //Check IP address from shared Internet { $IPaddress = $_SERVER[''HTTP_CLIENT_IP'']; } elseif (!empty($_SERVER[''HTTP_X_FORWARDED_FOR''])) //To check IP address is passed from the proxy { $IPaddress = $_SERVER[''HTTP_X_FORWARDED_FOR'']; } else { $IPaddress = $_SERVER[''REMOTE_ADDR'']; } return $IPaddress; }

Source


Aquí hay una forma más corta y limpia de obtener la dirección IP:

function get_ip_address(){ foreach (array(''HTTP_CLIENT_IP'', ''HTTP_X_FORWARDED_FOR'', ''HTTP_X_FORWARDED'', ''HTTP_X_CLUSTER_CLIENT_IP'', ''HTTP_FORWARDED_FOR'', ''HTTP_FORWARDED'', ''REMOTE_ADDR'') as $key){ if (array_key_exists($key, $_SERVER) === true){ foreach (explode('','', $_SERVER[$key]) as $ip){ $ip = trim($ip); // just to be safe if (filter_var($ip, FILTER_VALIDATE_IP, FILTER_FLAG_NO_PRIV_RANGE | FILTER_FLAG_NO_RES_RANGE) !== false){ return $ip; } } } } }

¡Espero que ayude!

Su código parece estar bastante completo ya, no puedo ver ningún error (aparte de las advertencias de IP habituales), cambiaría la función validate_ip() para confiar en la extensión del filtro:

public function validate_ip($ip) { if (filter_var($ip, FILTER_VALIDATE_IP, FILTER_FLAG_NO_PRIV_RANGE | FILTER_FLAG_NO_RES_RANGE) === false) { return false; } self::$ip = sprintf(''%u'', ip2long($ip)); // you seem to want this return true; }

También su fragmento de HTTP_X_FORWARDED_FOR se puede simplificar a partir de esto:

// check for IPs passing through proxies if (!empty($_SERVER[''HTTP_X_FORWARDED_FOR''])) { // check if multiple ips exist in var if (strpos($_SERVER[''HTTP_X_FORWARDED_FOR''], '','') !== false) { $iplist = explode('','', $_SERVER[''HTTP_X_FORWARDED_FOR'']); foreach ($iplist as $ip) { if ($this->validate_ip($ip)) return $ip; } } else { if ($this->validate_ip($_SERVER[''HTTP_X_FORWARDED_FOR''])) return $_SERVER[''HTTP_X_FORWARDED_FOR'']; } }

A esto:

// check for IPs passing through proxies if (!empty($_SERVER[''HTTP_X_FORWARDED_FOR''])) { $iplist = explode('','', $_SERVER[''HTTP_X_FORWARDED_FOR'']); foreach ($iplist as $ip) { if ($this->validate_ip($ip)) return $ip; } }

También es posible que desee validar las direcciones IPv6.


/** * Sanitizes IPv4 address according to Ilia Alshanetsky''s book * "php|architect?s Guide to PHP Security", chapter 2, page 67. * * @param string $ip An IPv4 address */ public static function sanitizeIpAddress($ip = '''') { if ($ip == '''') { $rtnStr = ''0.0.0.0''; } else { $rtnStr = long2ip(ip2long($ip)); } return $rtnStr; } //--------------------------------------------------- /** * Returns the sanitized HTTP_X_FORWARDED_FOR server variable. * */ public static function getXForwardedFor() { if (isset($_SERVER[''HTTP_X_FORWARDED_FOR''])) { $rtnStr = $_SERVER[''HTTP_X_FORWARDED_FOR'']; } elseif (isset($HTTP_SERVER_VARS[''HTTP_X_FORWARDED_FOR''])) { $rtnStr = $HTTP_SERVER_VARS[''HTTP_X_FORWARDED_FOR'']; } elseif (getenv(''HTTP_X_FORWARDED_FOR'')) { $rtnStr = getenv(''HTTP_X_FORWARDED_FOR''); } else { $rtnStr = ''''; } // Sanitize IPv4 address (Ilia Alshanetsky): if ($rtnStr != '''') { $rtnStr = explode('', '', $rtnStr); $rtnStr = self::sanitizeIpAddress($rtnStr[0]); } return $rtnStr; } //--------------------------------------------------- /** * Returns the sanitized REMOTE_ADDR server variable. * */ public static function getRemoteAddr() { if (isset($_SERVER[''REMOTE_ADDR''])) { $rtnStr = $_SERVER[''REMOTE_ADDR'']; } elseif (isset($HTTP_SERVER_VARS[''REMOTE_ADDR''])) { $rtnStr = $HTTP_SERVER_VARS[''REMOTE_ADDR'']; } elseif (getenv(''REMOTE_ADDR'')) { $rtnStr = getenv(''REMOTE_ADDR''); } else { $rtnStr = ''''; } // Sanitize IPv4 address (Ilia Alshanetsky): if ($rtnStr != '''') { $rtnStr = explode('', '', $rtnStr); $rtnStr = self::sanitizeIpAddress($rtnStr[0]); } return $rtnStr; } //--------------------------------------------------- /** * Returns the sanitized remote user and proxy IP addresses. * */ public static function getIpAndProxy() { $xForwarded = self::getXForwardedFor(); $remoteAddr = self::getRemoteAddr(); if ($xForwarded != '''') { $ip = $xForwarded; $proxy = $remoteAddr; } else { $ip = $remoteAddr; $proxy = ''''; } return array($ip, $proxy); }