PHP에서 리퍼러 결정


102

현재 페이지를 보냈거나 호출 한 (AJAX를 통해) 페이지를 결정하는 가장 안정적이고 안전한 방법은 무엇입니까? $_SERVER['HTTP_REFERER']안정성이 부족하기 때문에 를 사용하고 싶지 않으며 내 사이트에서 발생한 요청에서만 호출되는 페이지가 필요합니다.

편집 : 일련의 작업을 수행하는 스크립트가 내 웹 사이트의 페이지에서 호출되는지 확인하려고합니다.


5
$ _SERVER [ 'HTTP_REFERER']가 신뢰할 수없는 이유는 무엇입니까?
Milan Babuškov

9
PHP 구현은 안정적입니다. 문제는 브라우저가 이것을 전송하지 않으며 원하는 경우 수정할 수도 있다는 것입니다. 따라서 클라이언트 측에서 옳은 것이 신뢰할 수 없습니다.
Biri

2
가능한 방법은 페이지의 한 필드에 고유 키 (예 : GUID)를 입력하고 다음 요청에서 다시 보내는 것입니다.
PhiLho

서버의 IP 주소를 확인하고 $_SERVER[REMOTE_ADDR].

답변:


93

REFERER는 HTTP 프로토콜의 일부로 클라이언트 브라우저에 의해 전송되므로 실제로 신뢰할 수 없습니다. 거기에 없을 수도 있고, 위조되었을 수도 있고, 보안상의 이유라면 믿을 수 없을 수도 있습니다.

요청이 사이트에서 오는지 확인하려면 할 수 없지만 사용자가 사이트를 방문했는지 및 / 또는 인증되었는지 확인할 수 있습니다. 쿠키는 AJAX 요청으로 전송되므로 신뢰할 수 있습니다.


5
이 방법을 사용하려면, 당신은 여전히 CSRF 방지 할뿐만 아니라 참조 페이지를 확인해야합니다 en.wikipedia.org/wiki/Cross-site_request_forgery
JD Isaacks

17
이상적으로는 CSRF 공격을 방지하기 위해 사용자 당 (편집증 인 경우 요청 당) 세션 당 고유 한 토큰을 사용해야합니다. 리퍼러를 확인하는 것은 난독 화에 의한 보안 일뿐 실제 솔루션이 아닙니다.
Seldaek 2010

3
@Seldaek 아니요, 참조자를 확인하는 것은 '난독 화에 의한 보안'이 아닙니다. 피해자의 브라우저에 의해 전송 된 리퍼러를 제어 할 수있는 CSRF 공격을 수행하려는 공격자는, 그래서 확인 하지 CSRF에 대한 보호. 그러나 리퍼러 확인 접근 방식에는 사이트에 오픈 리디렉션이있는 경우 취약한 상태를 유지하고 리퍼러를 제거하는 사용자 에이전트가 중단되는 등의 단점 이 있기 때문에 대신 CSRF 토큰을 사용해야한다는 귀하의 결론을지지 할 것 입니다.
Mark Amery

@MarkAmery는 물론 방어하려는 대상에 따라 다르지만 클라이언트 별 http 헤더를 사용하는 것은 전반적으로 매우 강력한 보안 모델이 아닙니다.
Seldaek

23

내가 가장 잘 찾은 것은 CSRF 토큰이며 참조자를 확인해야하는 링크를 위해 세션에 저장합니다.

따라서 FB 콜백을 생성하는 경우 다음과 같이 표시됩니다.

$token = uniqid(mt_rand(), TRUE);
$_SESSION['token'] = $token;
$url = "http://example.com/index.php?token={$token}";

그러면 index.php는 다음과 같습니다.

if(empty($_GET['token']) || $_GET['token'] !== $_SESSION['token'])
{
    show_404();
} 

//Continue with the rest of code

모든 보안 페이지에 대해 이와 동일한 작업을 수행하는 보안 사이트를 알고 있습니다.


1
다음은 CSRF 토큰에 대한 자세한 링크입니다. en.wikipedia.org/wiki/Cross-site_request_forgery
We0

7
당신은 확실히는 것을인가 $_GET['token'] == $_SESSION['token']하지 $_GET['token'] !== $_SESSION['token']?
Timo Huovinen 2014

17

사용 $ _SERVER [ 'HTTP_REFERER를']

사용자 에이전트를 현재 페이지로 연결 한 페이지 (있는 경우)의 주소입니다. 이것은 사용자 에이전트에 의해 설정됩니다. 모든 사용자 에이전트가이를 설정하는 것은 아니며 일부는 HTTP_REFERER를 기능으로 수정하는 기능을 제공합니다. 요컨대, 정말 신뢰할 수 없습니다.

if (!empty($_SERVER['HTTP_REFERER'])) {
    header("Location: " . $_SERVER['HTTP_REFERER']);
} else {
    header("Location: index.php");
}
exit;

0

이를 확인할 수있는 신뢰할 수있는 방법이 없습니다. 그것이 어디에서 왔는지 알려주는 것은 정말로 고객의 손에 달려 있습니다. 웹 사이트의 일부 페이지에만있는 쿠키 또는 세션 정보를 사용한다고 상상할 수 있지만 그렇게하면 북마크에 대한 사용자 경험이 깨질 수 있습니다.


0

모든 가짜 리퍼러 문제를 읽은 후 남은 옵션은 하나뿐입니다. 즉, 리퍼러로 추적하려는 페이지는 세션에 유지되어야하며, 리퍼러 페이지 값이있는 경우 세션을 확인하고 다른 방법으로 작업을 수행하는 ajax로 호출해야합니다. 동작.

반면에 다른 페이지를 요청하는 동안 리퍼러 세션 값을 null로 만듭니다.

세션 변수는 욕구 페이지 요청에만 설정됩니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.