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

102

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

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

UnkwnTech
источник
5
Почему вы говорите, что $ _SERVER ['HTTP_REFERER'] ненадежен?
Милан Бабушков, 03
9
Реализация PHP надежна. Проблема в том, что это ни разу не отправляет браузер, и вы даже можете изменить его, если хотите. Так что это ненадежно, что правильно со стороны клиента.
Бири
2
Возможный способ - поместить уникальный ключ (например, GUID) в одно поле вашей страницы и отправить его обратно в следующем запросе.
PhiLho
Узнай IP-адрес сервера и используй $_SERVER[REMOTE_ADDR].

Ответы:

93

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

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

Seldaek
источник
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

Я знаю безопасные сайты, которые делают то же самое для всех своих защищенных страниц.

We0
источник
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 вызывается, а затем проверять в сеансе, имеет ли она значение страницы реферера, и выполнять действие в противном случае нет действие.

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

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

Justnajm
источник