사용자가 PHP의 localhost에 있는지 어떻게 알 수 있습니까?


99

즉, 내 웹 응용 프로그램을 사용하는 사람이 해당 응용 프로그램이있는 서버에 있는지 어떻게 알 수 있습니까? 내가 올바르게 기억하면 PHPMyAdmin은 보안상의 이유로 이와 같은 작업을 수행합니다.

답변:


177

$_SERVER['REMOTE_ADDR']웹 서버에서 요청하는 클라이언트의 IP 주소를 사용할 수도 있습니다 .

$whitelist = array(
    '127.0.0.1',
    '::1'
);

if(!in_array($_SERVER['REMOTE_ADDR'], $whitelist)){
    // not valid
}

2
이것은 실제로 IP를 스푸핑하는 것보다 쉽게 ​​깨뜨릴 수 있습니다. 정말 변경해야합니다.
Pekka

3
@ skcin7이 서버 설정일 수 있습니다. 확인해 봐.
mauris

4
@Pekka 웃은 예를 들어 보낼 수 Host: 127.0.0.1있으며에 채워질 HTTP_HOST것이므로 신뢰할 수있는 방법이 아닙니다.
Dejan Marjanović

4
예, 이것은 나쁜 조언이며 현재 형식이며 편집하거나 반대 투표해야합니다.
Pekka

3
IPv6를 잊지 마세요 :$whitelist = array('127.0.0.1', '::1');
CrazyMax

26

보완, 기능으로서 ...

function isLocalhost($whitelist = ['127.0.0.1', '::1']) {
    return in_array($_SERVER['REMOTE_ADDR'], $whitelist);
}

5
좋은 방법으로 "else return false"를 추가하는 것이 좋습니다. 함수가 항상 부울 값을 반환하도록합니다. 또는 "if"를 완전히 제거하고 대신 "return in_array ($ _SERVER [ 'REMOTE_ADDR'], $ whitelist);"
Joe Irby

15

새로운 OS 사용자 (Win 7, 8)는 화이트리스트 배열에 IPV6 형식 원격 주소를 포함해야 할 수도 있습니다.

$whitelist = array('127.0.0.1', "::1");

if(!in_array($_SERVER['REMOTE_ADDR'], $whitelist)){
    // not valid
}

14

$_SERVER["REMOTE_ADDR"]사용자의 IP를 알려야합니다. 하지만 스푸핑이 가능합니다.

이 현상금 질문 에서 매우 자세한 토론을 확인하십시오 .

PHPMyAdmin으로 기억하는 것은 다른 것 같습니다. 많은 MySQL 서버는 보안상의 이유로 localhost에서만 액세스 할 수 있도록 구성되어 있습니다.


일부 MySQL 서버는 공용 인터페이스에 바인딩하지 않음으로써 구성된다는 점에 주목할 가치가 있습니다. 마찬가지로, 동일한 방식으로 PHP 애플리케이션을 제한하려는 경우 내부 인터페이스에만 바인딩 된 아파치 인스턴스를 통해 제공하는 것을 고려해야합니다.
Frank Farmer

8

미안하지만이 모든 대답은 나에게 끔찍한 것 같습니다. 어떤 의미에서 모든 기계가 "localhost"이기 때문에 질문을 바꾸는 것이 좋습니다.

문제는 다음과 같아야합니다. 실행되는 컴퓨터에 따라 다른 코드 경로를 어떻게 실행합니까?

제 생각에는 가장 쉬운 방법은 DEVMACHINE 또는 원하는 파일을 만든 다음 간단히 확인하는 것입니다.

file_exists ( 'DEVMACHINE')

라이브 호스팅 환경에 업로드 할 때이 파일을 제외해야합니다!

이 솔루션은 네트워크 구성에 의존하지 않고 스푸핑 될 수 없으며 실행중인 "라이브 코드"와 "개발 코드"간에 쉽게 전환 할 수 있습니다.


6

이것은 $_SERVER['HTTP_HOST']쉽게 위조되는 http 헤더의 값이기 때문에 사용해서는 안되는 것 같습니다 .

당신도 사용할 수 있습니다 $_SERVER["REMOTE_ADDR"]. 이것은 더 안전한 값이지만 가짜도 가능합니다. 이것은 remote_addr아파치 반환에 결과 주소입니다.


REMOTE_ADDR위조가 가능하지만 127.0.0.1또는 로 위조하려는 경우 ::1시스템을 손상시켜야합니다. 스푸핑 REMOTE_ADDR은 가장 걱정할 필요가 없습니다. 관련 대답 - stackoverflow.com/a/5092951/3774582
거위

1

고정 IP동적 이름 을 지원 하는 화이트리스트 / 허용 목록 을 갖고 싶은 경우 .

예를 들면 :

$whitelist = array("localhost", "127.0.0.1", "devel-pc.ds.com", "liveserver.com");
if (!isIPWhitelisted($whitelist)) die();

이런 식으로 (확실히) 감지 할 수있는 이름 / IP 목록을 설정할 수 있습니다. 동적 이름은 다른 지점에서 액세스하는 데 더 많은 유연성을 추가합니다.

여기에는 두 가지 공통 옵션이 있습니다. 로컬 호스트 파일에 이름을 설정 하거나 어디에서나 찾을 수있는 하나의 동적 이름 공급자 를 사용할 수 있습니다.

이 함수는 gethostbyname이 매우 느린 함수이기 때문에 결과를 캐시합니다.

이를 위해이 기능을 구현했습니다.

function isIPWhitelisted($whitelist = false)
{
    if ( isset($_SESSION) && isset($_SESSION['isipallowed']) )
        { return $_SESSION['isipallowed'];  }

    // This is the whitelist
    $ipchecklist = array("localhost", "127.0.0.1", "::1");
    if ($whitelist) $ipchecklist = $whitelist;

    $iplist = false;
    $isipallowed = false;

    $filename = "resolved-ip-list.txt";
    $filename = substr(md5($filename), 0, 8)."_".$filename; // Just a spoon of security or just remove this line

    if (file_exists($filename))
    {
        // If cache file has less than 1 day old use it
        if (time() - filemtime($filename) <= 60*60*24*1)
            $iplist = explode(";", file_get_contents($filename)); // Read cached resolved ips
    }

    // If file was not loaded or found -> generate ip list
    if (!$iplist)
    {
        $iplist = array(); $c=0;
        foreach ( $ipchecklist as $k => $iptoresolve )
        {
            // gethostbyname: It's a VERY SLOW function. We really need to cache the resolved ip list
            $ip = gethostbyname($iptoresolve);
            if ($ip != "") $iplist[$c] = $ip;
            $c++;
        }

        file_put_contents($filename, implode(";", $iplist));
    }

    if (in_array($_SERVER['REMOTE_ADDR'], $iplist)) // Check if the client ip is allowed
        $isipallowed = true;

    if (isset($_SESSION)) $_SESSION['isipallowed'] = $isipallowed;

    return $isipallowed;
}

더 나은 안정성을 위해 @Pekka"이 현상금 질문" 으로 자신의 게시물 에서 언급 한 get_ip_address ()에 대한 $ _SERVER [ 'REMOTE_ADDR'] 을 대체 할 수 있습니다.


1
나는 누군가가 내 대답에 부정적인 점수를 설정했지만 동적 이름 확인을 분명히 제공하고 다른 사람들은 그렇지 않은 이유를 모르겠습니다. DNS 확인이 느리기 때문에 캐싱 확인이 필요합니다.
Heroselohim

1

$_SERVER['SERVER_ADDR'] === $_SERVER['REMOTE_ADDR']클라이언트가 서버와 동일한 시스템에 있는지 확인 하기 위해 비교 하는 것은 어떻습니까?


$_SERVER['SERVER_ADDR']항상 서버 주소를 안정적으로 반환하지는 않습니다. 예를 들어로드 밸런서를 사용하는 경우 내가 믿는로드 밸런서의 IP 주소를 반환합니다.
Mike W

-2

쉬운 답을 찾았습니다.

모든 로컬 드라이브에는 C : 또는 D : 또는 F : ... 등이 있기 때문입니다.

두 번째 문자가 다음과 같은지 감지하십시오.

if ( substr_compare(getcwd(),":",1,1) == 0)
{
echo '<script type="text/javascript">alert(" The working dir is at the local computer ")</script>';
    $client_or_server = 'client';
}
else
{
echo '<script type="text/javascript">alert(" The working dir is at the server ")</script>';
    $client_or_server = 'server';
}
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.