Определение Referer в PHP


102

Каков наиболее надежный и безопасный способ определить, какая страница отправила или вызвала (через AJAX) текущую страницу. Я не хочу использовать $_SERVER['HTTP_REFERER']из-за (недостаточной) надежности, и мне нужно, чтобы вызываемая страница исходила только от запросов, исходящих с моего сайта.

Изменить: я хочу убедиться, что сценарий, который выполняет серию действий, вызывается со страницы на моем веб-сайте.


5
Почему вы говорите, что $ _SERVER ['HTTP_REFERER'] ненадежен?
Милан Бабушков, 03

9
Реализация PHP надежна. Проблема в том, что это ни разу не отправляет браузер, и вы даже можете изменить его, если хотите. Так что это ненадежно, что правильно со стороны клиента.
Бири

2
Возможный способ - поместить уникальный ключ (например, GUID) в одно поле вашей страницы и отправить его обратно в следующем запросе.
PhiLho

Узнай IP-адрес сервера и используй $_SERVER[REMOTE_ADDR].

Ответы:


93

REFERER отправляется браузером клиента как часть протокола HTTP и поэтому действительно ненадежен. Его может не быть, он может быть подделан, ему просто нельзя доверять, если это из соображений безопасности.

Если вы хотите проверить, поступает ли запрос с вашего сайта, вы не можете, но вы можете подтвердить, что пользователь был на вашем сайте и / или прошел аутентификацию. Файлы cookie отправляются в запросах AJAX, поэтому вы можете на это положиться.


5
Если вы хотите использовать этот метод, вам все равно следует проверить
реферер,

17
В идеале вы должны использовать уникальный токен для каждого сеанса для каждого пользователя (для каждого запроса, если вы параноик), чтобы предотвратить атаки CSRF. Проверка реферера - это просто безопасность путем обфускации и не совсем реальное решение.
Seldaek

3
@Seldaek нет, проверка реферера - это не «безопасность путем обфускации». Злоумышленник, пытающийся выполнить CSRF-атаку, не может контролировать реферер, отправленный браузером жертвы, поэтому проверка его действительно защищает от CSRF. Тем не менее, я согласен с вашим выводом, что вместо этого вам следует использовать токен CSRF, поскольку подход с проверкой реферера имеет недостатки, в том числе делает вас уязвимым, если у вас есть открытое перенаправление на вашем сайте, и нарушение для пользовательских агентов, которые удаляют референт.
Марк Эмери

@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
Вот ссылка для получения дополнительной информации о
токенах

7
Вы уверены, что это так $_GET['token'] == $_SESSION['token']и нет $_GET['token'] !== $_SESSION['token']?
Timo Huovinen

17

Использование $ _SERVER ['HTTP_REFERER']

Адрес страницы (если есть), которая направила пользовательский агент на текущую страницу. Это устанавливается пользовательским агентом. Не все пользовательские агенты будут устанавливать это, а некоторые предоставляют возможность изменять HTTP_REFERER как функцию. Короче говоря, этому нельзя верить.

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

0

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


0

У нас остался только один вариант после прочтения всех проблем с фальшивым реферером: т.е. страница, которую мы хотим отслеживать как реферер, должна оставаться в сеансе, и как ajax вызывается, а затем проверять в сеансе, имеет ли она значение страницы реферера, и выполнять действие в противном случае нет действие.

С другой стороны, когда он запрашивает любую другую страницу, тогда значение сеанса реферера становится нулевым.

Помните, что переменная сеанса устанавливается только при запросе страницы желания.

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.