JSON Web Tokens давно стали стандартом авторизации в веб-приложениях и API. Их удобство обманчиво: неправильно настроенный JWT открывает дорогу к полной компрометации учётных записей без единого запроса к базе данных. В этом материале — без воды и маркетинга: как устроены токены, почему они ломаются и как этичный хакер (и разработчик) должен смотреть на них во время аудита.
Что такое JWT и зачем он нужен
JWT (JSON Web Token) — это компактный токен, с помощью которого сервер может проверить подлинность клиента без хранения сессии. Типичный сценарий:
Анатомия 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, а секрет представляет собой короткое слово или пароль по умолчанию, его можно подобрать перебором.
Практика пентестера:
3. Смешение алгоритмов (Key Confusion)
Сервер может быть настроен на асимметричный алгоритм RS256, но проверять и токены с HS256, используя при этом публичный ключ как секрет HMAC. Если у злоумышленника есть открытый ключ (он часто доступен по URL вроде /.well-known/jwks.json), он может:
4. Инъекции в kid и другие параметры заголовка
Параметр kid (Key ID) в заголовке JWT часто используется для выбора ключа. Если значение kid напрямую подставляется в SQL-запрос, путь к файлу или shell-команду без фильтрации, возникают:
Инструменты для анализа и взлома JWT
Хороший специалист не начинает ручной разбор без инструментов. Вот минимальный набор:
Обороняющаяся сторона должна соблюдать жёсткие правила, иначе даже самый стойкий алгоритм не спасёт:
После освоения базовых атак углублённый пентест JWT идёт через:
Что такое JWT и зачем он нужен
JWT (JSON Web Token) — это компактный токен, с помощью которого сервер может проверить подлинность клиента без хранения сессии. Типичный сценарий:
- Пользователь входит в систему, сервер создаёт JWT и отдаёт клиенту.
- Клиент сохраняет токен (обычно в localStorage или cookie) и прикрепляет к каждому запросу.
- Сервер проверяет подпись JWT, не обращаясь к БД.
Анатомия 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, а секрет представляет собой короткое слово или пароль по умолчанию, его можно подобрать перебором.
Практика пентестера:
- Извлечь токен из трафика или хранилища браузера.
- Пропустить через hashcat (режим 16500) со словарём.
- Найденный секрет использовать для подписи произвольного payload — от имени любого пользователя.
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
Хороший специалист не начинает ручной разбор без инструментов. Вот минимальный набор:
- jwt.io — визуальный дебаггер, позволяет быстро посмотреть содержимое токена.
- jwt_tool (Python) — главный молоток для пентестера: поддерживает все описанные атаки, фаззинг заголовков, подбор секрета и эксплуатацию kid.
- Burp Suite с расширением JWT Editor — позволяет перехватывать, редактировать и переподписывать токены на лету.
- hashcat — для offline-подбора HMAC-секрета.
Обороняющаяся сторона должна соблюдать жёсткие правила, иначе даже самый стойкий алгоритм не спасёт:
- Белый список алгоритмов — сервер принимает только явно указанные (например, RS256), игнорируя заголовок.
- Сильный секрет — для HMAC не менее 256 бит случайных данных, хранится в переменных окружения.
- Короткое время жизни токена (exp) и механизм refresh-токенов.
- Не хранить чувствительные данные в payload — всё содержимое читаемо любым клиентом.
- Валидировать все параметры заголовка — kid, jku, x5u фильтровать по белому списку, не подставлять напрямую.
- Мониторинг отзыва — реализовать блокировку токенов (blacklist/revocation) для компрометированных учётных записей.
После освоения базовых атак углублённый пентест JWT идёт через:
- атаки на библиотеки (CVE в реализации);
- эксплуатацию неправильного парсинга в микросервисной архитектуре;
- обход ограничений через вложенные токены;
- анализ криптографических нюансов (ECDSA, EdDSA).