Перейти к содержимому
← Каталог golang Auth Bypass

JWT Authentication: Взлом слабой криптографии

В этой лаборатории сервер использует JWT для авторизации, но совершает сразу две критические ошибки: использует слабый секретный ключ и доверяет заголовку alg.

hardgolangPro
Задача
# JWT: обход аутентификации через приём небезопасного алгоритма подписи ## Сценарий Вы — аудитор безопасности **SecureShop**. Приложение использует JWT-токены для аутентификации: при входе сервер выдаёт токен, который хранится в cookie `token` и проверяется при каждом запросе. Команда уверена, что эндпоинт-валидатор JWT настроен корректно: используется стандартная библиотека golang-jwt, секрет хранится на сервере, токен подписывается HMAC. По данным внутреннего аудита, в админ-панели хранится конфиденциальная метка, доступная только пользователям с ролью администратора; её требуется извлечь, имея только обычную учётную запись. ## Цель 1. Изучите структуру JWT-токена, выдаваемого сервером после логина обычного пользователя — какие поля в нём есть, какой алгоритм указан в заголовке, какие claims контролируются сервером. 2. Найдите способ создать токен с произвольными claims без знания серверного секрета — иначе говоря, обойти криптографическую проверку подписи. 3. Получите доступ к админ-панели и извлеките флаг. ## Теория JWT-токен состоит из трёх base64url-частей, разделённых точками: заголовка (с указанием алгоритма подписи), payload (с claims — данными о пользователе) и подписи. Подпись доказывает, что claims не изменялись после выдачи токена. Однако спецификация JWT исторически включала алгоритм `none`, обозначающий «токен без подписи» — он был введён для случаев передачи через уже защищённые каналы (mTLS, локальный IPC), но в публичных HTTP-API стал источником массовых уязвимостей: если сервер принимает токены с `alg: none`, проверка подписи фактически отсутствует, и атакующий может предъявить любой токен с любыми claims. **Уязвимый паттерн:** ```go // Список разрешённых алгоритмов включает "none" — подпись не проверяется token, _ := jwt.Parse(tokenStr, func(t *jwt.Token) (interface{}, error) { if t.Method.Alg() == "none" { return jwt.UnsafeAllowNoneSignatureType, nil } return jwtSecret, nil }, jwt.WithValidMethods([]string{"HS256", "none"})) ``` Различные JWT-библиотеки имеют разные реакции на `alg: none` по умолчанию: одни принимают (старые версии), другие требуют явного opt-in (как `WithValidMethods` в golang-jwt/v5). Уязвимость возникает, когда разработчик добавляет `"none"` в whitelist алгоритмов — обычно по ошибке, копируя пример с docs или решая «специальный случай для тестирования». ## Точка входа атаки | Параметр | Значение | |----------|----------| | Учётные данные обычного пользователя | `demo` / `demo` | | Эндпоинт логина | `POST /login` (выдаёт cookie `token` с JWT) | | Привилегированный эндпоинт | `GET /admin` (требует `role: admin` в JWT-payload) |
🚧 Сайт в разработке. Полный функционал пока недоступен. Все вопросы — support@hackandfix.ru