Безопасность PHP: Почему использование $_SERVER[‘HTTP_REFERER’] в логике авторизации — это дыра в безопасности?

## Почему $_SERVER[‘HTTP_REFERER’] — это дыра в безопасности

`$_SERVER[‘HTTP_REFERER’]` — это HTTP-заголовок `Referer`, который браузер отправляет серверу, указывая, с какой страницы пришёл пользователь. На первый взгляд кажется удобным: «если пользователь пришёл со страницы /admin/dashboard, значит, он авторизован». Но это фундаментально неверное допущение.

### Главная проблема: заголовок полностью контролируется клиентом

HTTP-заголовок `Referer` формируется на стороне клиента и передаётся серверу. Это означает, что любой человек может отправить произвольное значение этого заголовка с помощью:

— **curl**: `curl -H «Referer: https://example.com/admin/dashboard» https://example.com/secret`
— **Postman** или любого HTTP-клиента
— **Браузерных расширений** или DevTools
— **Собственных скриптов** на любом языке

Таким образом, злоумышленник может подделать заголовок `Referer` и притвориться, что пришёл с «доверенной» страницы, полностью обойдя проверку.

### Пример уязвимого кода

php
// ОПАСНО! Никогда так не делайте
if ($_SERVER[‘HTTP_REFERER’] === ‘https://example.com/admin/login’) {
// Даём доступ к защищённому ресурсу
showAdminPanel();
}

Этот код взламывается одной командой в терминале.

### Дополнительные проблемы

1. **Заголовок может отсутствовать**. Браузеры не гарантируют отправку `Referer`. Политика `Referrer-Policy`, режим инкогнито, корпоративные прокси и антивирусы могут обрезать или полностью удалять этот заголовок. Легитимный пользователь потеряет доступ.

2. **Зависимость от поведения браузера**. Разные браузеры и версии HTTP ведут себя по-разному в отношении отправки `Referer`.

3. **HTTPS → HTTP переходы**. При переходе с HTTPS на HTTP заголовок `Referer` не передаётся вовсе.

### Как правильно реализовать авторизацию

Вместо проверки `Referer` используйте надёжные механизмы:

— **Серверные сессии** (`$_SESSION`): после успешной аутентификации устанавливайте флаг в сессии (`$_SESSION[‘is_authenticated’] = true`) и проверяйте его на каждой защищённой странице.
— **JWT-токены**: подписанные токены, которые нельзя подделать без секретного ключа.
— **CSRF-токены**: для защиты форм используйте уникальные одноразовые токены, хранящиеся в сессии.
— **Middleware/Guard**: выносите логику проверки прав в отдельный слой приложения.

### Допустимое использование Referer

`$_SERVER[‘HTTP_REFERER’]` можно использовать только для **неответственных** задач: аналитики, редиректа после логина на предыдущую страницу (с валидацией URL), логирования. Никогда — для принятия решений о доступе.

### Вывод

Любые данные, поступающие от клиента — заголовки, куки без подписи, параметры URL — считаются ненадёжными. `$_SERVER[‘HTTP_REFERER’]` — это просто строка, которую злоумышленник контролирует полностью. Авторизация должна строиться исключительно на серверных механизмах проверки подлинности.


Задайте вопрос нейросети

Не нашли ответ? Спросите ИИ — он подготовит развёрнутую статью.