У меня есть простой скрипт, который определяет 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']
? Или на самом деле это необязательно?
Если причина, по которой вы хотите узнать IP-адрес клиента, действительно важна, закрутите все это.
Любое из этих значений заголовка может свободно подделываться.
REMOTE_ADDR
– единственная действительно достоверная информация, так как она передается вам вашим веб-сервером, который обрабатывает запрос. Это также может быть теоретически фальсифицировано , но это намного сложнее, чем подделка значения заголовка и совершенно другого класса атаки.
Есть исключения в очень, очень специфических средах хостинга за обратными прокси. В этих случаях человек, управляющий этим прокси, сможет указать, какое значение заголовка вам нужно проверить.
Из класса заявок Коханаса:
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']; }
эта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']; }
не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']; }
эта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']; }
не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
в этом случае.
Не проверяйте заголовки HTTP_*
для IP- HTTP_*
клиента, если вы специально не знаете, что ваше приложение настроено за обратным прокси. Доверие к значениям этих заголовков безоговорочно позволит пользователям обманывать свой IP-адрес.
Единственное поле $_SERVER
содержащее надежное значение, – REMOTE_ADDR
.
Две вещи практически идентичны. В найденном скрипте автор просто выполняет проверку, если элемент в массиве установлен, прежде чем проверять, что он не пуст.
Что касается использования empty()
-функции вместо сравнения, проверьте http://php.net/empty . Поскольку вы имеете дело с переменной, заданной средой, а не с пользовательским вводом, не имеет значения, какой из двух выбранных вами вариантов. Так что ваш скрипт должен быть отлично