Будет ли значение набора $ _SERVER ['HTTP_CLIENT_IP'] пустой строкой? - PullRequest
8 голосов
/ 02 октября 2011

У меня есть простой скрипт, который определяет IP-адрес пользователя:

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

Сейчас в сети где-то я видел кого-то, использующего этот скрипт:

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

Мне было интересно, сломана ли моя реализация. Нужно ли проверять, является ли значение $_SERVER['HTTP_CLIENT_IP'], $_SERVER['HTTP_X_FORWARDED_FOR'] или $_SERVER['REMOTE_ADDR'] пустым? Или это на самом деле не нужно?

Ответы [ 4 ]

14 голосов
/ 02 октября 2011

Если причина, по которой вы хотите узнать IP-адрес клиента, действительно важна, все это испортит.

Любое из этих значений заголовка может быть свободно подделано.

REMOTE_ADDR - единственная действительно достоверная информация, так как она передается вам вашим веб-сервером, который обрабатывает запрос. Теоретически это может быть также фальсифицировано , но это намного, намного сложнее, чем подделка значения заголовка и совершенно другой класс атаки.

Существуют исключения в очень специфических средах размещения за обратными прокси-серверами. В этих случаях человек, управляющий этим прокси-сервером, сможет определить, какое значение заголовка необходимо проверить.

8 голосов
/ 02 октября 2011

Из класса запроса Коханаса:

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

Это почти столько же, сколько получается.Обратите внимание на массив Request::$trusted_proxies и ваш $ip var в данном случае Request::$client_ip.

7 голосов
/ 02 октября 2011

Не проверяйте заголовки HTTP_* для IP-адреса клиента, если вы не знаете, что ваше приложение настроено за обратным прокси-сервером.Безоговорочное доверие значениям этих заголовков позволит пользователям подделывать их IP-адрес.

Единственное поле $_SERVER, содержащее надежное значение, - REMOTE_ADDR.

1 голос
/ 02 октября 2011

Эти две вещи практически идентичны .. В найденном вами сценарии автор просто проверяет, установлен ли элемент в массиве, прежде чем проверять, что он не пустой.

В отношениииспользуя empty() -функцию вместо сравнения, отметьте http://php.net/empty. Поскольку вы имеете дело с переменной, заданной средой, а не с пользовательским вводом, не имеет значения, какой из двух выбранных вами вариантов.Так что ваш сценарий должен быть в полном порядке

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...