JWT-токены под микроскопом: как хакеры подделывают сессии и как защититься

god

New member
Член команды
JSON Web Tokens давно стали стандартом авторизации в веб-приложениях и API. Их удобство обманчиво: неправильно настроенный JWT открывает дорогу к полной компрометации учётных записей без единого запроса к базе данных. В этом материале — без воды и маркетинга: как устроены токены, почему они ломаются и как этичный хакер (и разработчик) должен смотреть на них во время аудита.

Что такое JWT и зачем он нужен
JWT (JSON Web Token) — это компактный токен, с помощью которого сервер может проверить подлинность клиента без хранения сессии. Типичный сценарий:

  1. Пользователь входит в систему, сервер создаёт JWT и отдаёт клиенту.
  2. Клиент сохраняет токен (обычно в localStorage или cookie) и прикрепляет к каждому запросу.
  3. Сервер проверяет подпись JWT, не обращаясь к БД.
Именно отказ от серверного состояния делает JWT таким популярным в микросервисах и SPA, но одновременно создаёт поверхность для критических атак.

Анатомия JWT: три части, которые важно знать
Токен состоит из трёх Base64-encoded частей, разделённых точками:

text

header.payload.signature
Header — содержит алгоритм подписи, например {"alg":"HS256","typ":"JWT"}.
Payload — полезная нагрузка: ID пользователя, роль, срок действия (exp).
Signature — криптографическая подпись, вычисляемая по формуле:

text

HMACSHA256(base64UrlEncode(header) + "." + base64UrlEncode(payload), secret)
Если любая из трёх частей подделана и подпись не совпадает — токен невалиден. Так задумано. На практике всё ломается из-за ошибок конфигурации и доверия к данным из токена.

Главные уязвимости JWT: как ломают сессии
Разберём векторы, которые чаще всего находят на пентестах и bug bounty.

1. Отсутствие проверки алгоритма: «alg: none»
Самая опасная и до сих пор встречающаяся ошибка. Библиотеки на стороне сервера, которые не жёстко задают допустимый алгоритм, могут принять токен с заголовком "alg":"none". Такой токен не имеет подписи — сервер просто принимает payload как достоверный.

Атака: хакер меняет заголовок на alg:none, удаляет сигнатуру и, например, подставляет "role":"admin".
Инструмент: утилита jwt_tool (модуль None Attack) делает это одной командой.

Защита: всегда явно указывать на сервере список разрешённых алгоритмов (только RS256/HS256) и никогда не полагаться на значение из заголовка токена.

2. Слабый секрет в HMAC
Если JWT подписан с помощью HS256, а секрет представляет собой короткое слово или пароль по умолчанию, его можно подобрать перебором.

Практика пентестера:

  1. Извлечь токен из трафика или хранилища браузера.
  2. Пропустить через hashcat (режим 16500) со словарём.
  3. Найденный секрет использовать для подписи произвольного payload — от имени любого пользователя.
Типичные находки: secret, password, company_name, пустая строка.

3. Смешение алгоритмов (Key Confusion)
Сервер может быть настроен на асимметричный алгоритм RS256, но проверять и токены с HS256, используя при этом публичный ключ как секрет HMAC. Если у злоумышленника есть открытый ключ (он часто доступен по URL вроде /.well-known/jwks.json), он может:

  • Сменить алгоритм в заголовке на HS256.
  • Подписать вредоносный payload этим же публичным ключом.
  • Сервер успешно проверит токен, приняв публичный ключ за секрет.
Это классическая уязвимость, обнаруженная во многих библиотеках.

4. Инъекции в kid и другие параметры заголовка
Параметр kid (Key ID) в заголовке JWT часто используется для выбора ключа. Если значение kid напрямую подставляется в SQL-запрос, путь к файлу или shell-команду без фильтрации, возникают:

  • SQL-инъекции через kid → обход авторизации.
  • Path Traversal → чтение файлов.
  • Command Injection при вызове внешнего процесса для подписи.
В продвинутом пентесте JWT-заголовки анализируются так же пристально, как и HTTP-запросы.

Инструменты для анализа и взлома JWT
Хороший специалист не начинает ручной разбор без инструментов. Вот минимальный набор:

  • jwt.io — визуальный дебаггер, позволяет быстро посмотреть содержимое токена.
  • jwt_tool (Python) — главный молоток для пентестера: поддерживает все описанные атаки, фаззинг заголовков, подбор секрета и эксплуатацию kid.
  • Burp Suite с расширением JWT Editor — позволяет перехватывать, редактировать и переподписывать токены на лету.
  • hashcat — для offline-подбора HMAC-секрета.
Как защитить JWT-сессии: чеклист
Обороняющаяся сторона должна соблюдать жёсткие правила, иначе даже самый стойкий алгоритм не спасёт:

  1. Белый список алгоритмов — сервер принимает только явно указанные (например, RS256), игнорируя заголовок.
  2. Сильный секрет — для HMAC не менее 256 бит случайных данных, хранится в переменных окружения.
  3. Короткое время жизни токена (exp) и механизм refresh-токенов.
  4. Не хранить чувствительные данные в payload — всё содержимое читаемо любым клиентом.
  5. Валидировать все параметры заголовка — kid, jku, x5u фильтровать по белому списку, не подставлять напрямую.
  6. Мониторинг отзыва — реализовать блокировку токенов (blacklist/revocation) для компрометированных учётных записей.
Как эту тему развить в исследовании
После освоения базовых атак углублённый пентест JWT идёт через:

  • атаки на библиотеки (CVE в реализации);
  • эксплуатацию неправильного парсинга в микросервисной архитектуре;
  • обход ограничений через вложенные токены;
  • анализ криптографических нюансов (ECDSA, EdDSA).
Именно понимание внутренней механики JWT, а не бездумный запуск сканера, отличает сильного специалиста.
 
Вверх