Referer Bypass: обход контроля доступа через подмену заголовка
API-эндпоинт /api/admin/users проверяет заголовок Referer вместо роли пользователя. Атакующий может подделать заголовок и получить доступ к данным администратора.
mediumgolangPro
Задача
# Referer Bypass: ненадёжная авторизация через клиентский HTTP-заголовок
## Сценарий
Вы зарегистрированный пользователь интернет-магазина **SecureShop**. У приложения есть API-эндпоинт, возвращающий JSON со списком пользователей и сервисной информацией. Команда уверена, что эндпоинт безопасен — реализована проверка, разрешающая запросы только с админ-страниц приложения. По данным внутреннего аудита, этот эндпоинт раскрывает конфиденциальную метку в JSON-ответе; её требуется получить, имея только обычную учётную запись.
## Цель
1. Изучите механизм авторизации эндпоинта: какие именно атрибуты запроса проверяет сервер для определения «легитимного» источника.
2. Найдите способ имитировать «легитимный источник» с обычной учётной записи без необходимости получать admin-сессию.
3. Извлеките флаг из JSON-ответа admin-эндпоинта.
## Теория
Использование клиентских HTTP-заголовков (`Referer`, `Origin`, `User-Agent`, `X-Forwarded-For` без trust-цепочки) для **авторизации** — известный антипаттерн, документированный OWASP и описанный в CWE-293. Все HTTP-заголовки запроса формируются клиентом и могут быть произвольно подделаны через любой инструмент, отправляющий HTTP-запросы напрямую (curl, Burp, Python `requests`, custom HTTP-клиент). Браузер проставляет `Referer` автоматически при переходе по ссылке внутри сайта, но это не криптографическое доказательство — атакующий, отправляющий запрос напрямую, не ограничен поведением браузера.
**Уязвимый паттерн:**
```go
// Авторизация по клиентскому заголовку — обходится подменой
referer := r.Header.Get("Referer")
if !strings.Contains(referer, "secure-shop") && !strings.Contains(referer, r.Host) {
http.Error(w, "Access Denied", 403); return
}
// ... возвращает чувствительные данные
```
Авторизация в HTTP-приложении должна основываться на **серверных** атрибутах запроса: идентификаторе сессии (cookie с server-side state), JWT-токене с проверенной подписью, ролевых атрибутах из аутентифицированной сессии. Любая проверка по клиентскому полю — лишь UX-фильтр, не безопасность.
## Точка входа атаки
| Параметр | Значение |
|----------|----------|
| Учётные данные | `demo` / `demo` |
| API-эндпоинт | `GET /api/admin/users` (возвращает JSON с пользователями и секретами) |
| Цель | извлечь флаг из JSON-ответа эндпоинта |