2011-10-01 5 views
7

사용자의 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'] 값이 비어 있는지 확인해야합니까? 아니면 그렇게 할 필요가 실제로 있습니까?

+1

이 기능의 목적은 무엇입니까? 어떤면에서 보안과 관련이 있습니까? Beacause 인 경우 'REMOTE_ADDR'만 보람있는 것입니다. –

+0

에 따라 다름. 나는 그들의 서버 앞에서 프록시를 가지고있는 몇몇 호스팅 회사를 기억하고 있는데 그들은'REMOTE_ADDR'을 항상 '10.0.0.1'과 같은 프록시가되는 * local * IP로 밀어 넣습니다. 그래서 당신이 원한다면 'X_FORWARDED_FOR'와 함께 가야하는 클라이언트 IP를 얻으십시오. – klaustopher

답변

12

당신이 클라이언트의 IP 주소를 알아 내고 싶은 이유가 정말로 중요하다면,이 모든 것을 망쳐 놓으십시오.

이러한 헤더 값 중 하나 인은 자유롭게 스푸핑 될 수 있습니다.

REMOTE_ADDR은 요청을 처리하는 웹 서버에서 귀하에게 전송하는 유일한 신뢰할만한 정보입니다. 이론적으로는 falsified as well 일 수 있지만, 이는 헤더 값을 스푸핑하는 것보다 훨씬 어렵고 완전히 다른 공격 클래스입니다.

역 프록시가있는 매우 특정한 호스팅 환경에는 예외가 있습니다. 이 경우 해당 프록시를 관리하는 사람이 테스트해야하는 헤더 값을 알 수 있습니다.

+0

당신은 "자유 스푸핑 된"이라는 단어를 자세히 설명해 주시겠습니까? 제 자신과 같은 평신도가 이런 종류의 스크립트를 사용하는 웹 사이트를 스푸핑 할 수 있다는 것을 의미합니까? – Pacerier

+0

@Pacerier yup - 웹 사이트에 요청을하면 값 (예 : 다른 사람의 IP 주소)이있는'X_HTTP_FORWARDED_FOR' 헤더를 보낼 수 있습니다. curl이나 브라우저 플러그인을 사용하면 쉽게 할 수 있습니다. 정상적인 설정에서'REMOTE_ADDR'만이 신뢰할 수있는 유일한 IP 주소입니다. @ kemo의 스 니펫은 신뢰할 수있는 프록시에서 올 때만 헤더 값을 신뢰함으로써이를 고려합니다. –

+0

정보를 제공해 주셔서 감사합니다! 이 사람들은 여기에 http://stackoverflow.com/questions/444966/working-with-ipv6-addresses-in-php ** GetRealRemoteIp **처럼 함수의 이름을 짓는 것은 단순히 $ _SERVER [ "REMOTE_ADDR"] – Pacerier

1

두 가지 사실은 동일합니다. 발견 한 스크립트에서 저자는 어레이의 요소가 비어 있지 않은지 확인하기 전에 배열의 요소가 설정되어 있는지 확인하고 있습니다.

비교 대신 empty() -function을 사용하는 것에 대해서는 http://php.net/empty을 확인하십시오. 사용자 입력이 아닌 환경에 의해 설정된 변수를 다루기 때문에 두 가지 옵션 중 어느 것을 선택하든 상관 없습니다. 그래서 스크립트는 Kohanas '요청 클래스에서

+0

빈 체크를하고 있다는 것을 알고 있습니다. 그런 일을 할 필요가 있는지 궁금합니다. 다시 말해, 길이가 0 인 결과를 얻을 수 있습니까? – Pacerier

8

완벽하게 괜찮을 것 :

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

응용 프로그램이 역방향 프록시로 구성되어 있지 않다면 클라이언트 IP 용으로 HTTP_* 헤더를 확인하지 마십시오. 이러한 헤더의 값을 무조건적으로 신뢰하면 사용자는 자신의 IP 주소를 스푸핑 할 수 있습니다.

신뢰할 수있는 값을 포함하는 $_SERVER 필드는 REMOTE_ADDR입니다.

+0

Ic .. 나는 실제로이 스크립트를 가지고있다. http://stackoverflow.com/questions/444966/working-with-ipv6-addresses-in-php 왜 이런 종류의 IP를 사용하는 모든 사람들이 스크립트를 탐지하고 퍼팅하는지 설명 할 수 있는가? * 실제 IP *가 $ _SERVER [ "REMOTE_ADDR"]에 저장되어 있으면 * GetRealIp *라는 함수에서? – Pacerier

+1

그들은 안전하지 않은 코드를 작성하고 있기 때문입니다. 의견보기! – duskwuff

관련 문제