Распространённые ошибки при работе с JWT и их причины

JWT состоит из трёх частей: заголовок (header), полезная нагрузка (payload) и подпись (signature). Частая ошибка — воспринимать payload как защищённую область. На практике он лишь закодирован в Base64URL, но не зашифрован. Это приводит к утечке конфиденциальных данных, если внутрь токена помещаются пароли, ключи или персональная информация.

Причина: путаница между кодированием и шифрованием, а также неверное представление о безопасности токена.


Использование небезопасных алгоритмов

Одной из критических ошибок является использование алгоритма none или отсутствие строгой проверки алгоритма при верификации. Это позволяет злоумышленнику подменить подпись и сформировать валидный токен без знания секретного ключа.

Также часто встречается ситуация, когда сервер принимает токены, подписанные разными алгоритмами, не ограничивая список допустимых.

Причина: неправильная конфигурация библиотеки и отсутствие явного указания допустимых алгоритмов при проверке токена.


Смешивание симметричной и асимметричной криптографии

При работе с библиотекой jose возможно использование как симметричных алгоритмов (например, HS256), так и асимметричных (RS256, ES256). Ошибка возникает, когда публичный ключ используется как секрет для HMAC-алгоритма.

Это позволяет атакующему подписывать токены самостоятельно, если он имеет доступ к публичному ключу.

Причина: непонимание различий между типами алгоритмов и их областями применения.


Отсутствие проверки срока действия (exp)

JWT может содержать поле exp, указывающее срок действия токена. Игнорирование этого поля приводит к тому, что устаревшие токены продолжают считаться валидными.

Некоторые разработчики отключают проверку времени ради удобства тестирования и забывают вернуть её в продакшене.

Причина: упрощение логики проверки или неправильная настройка параметров верификации.


Игнорирование поля audience (aud)

Поле aud определяет, для какого сервиса предназначен токен. Если не проверять это значение, токен, выданный для одного сервиса, может быть использован в другом.

Причина: недооценка важности ограничения области применения токена.


Неправильная работа с секретами и ключами

Секретные ключи часто:

  • хранятся в коде
  • передаются через небезопасные каналы
  • имеют слишком простую структуру

В случае асимметричных ключей возможны ошибки при их загрузке, например, использование неправильного формата (PEM vs JWK).

Причина: отсутствие практики безопасного управления ключами и слабая интеграция с системами хранения секретов.


Повторное использование токенов без ротации

JWT часто используется как долгоживущий токен без механизма обновления. Это увеличивает риск компрометации: если токен украден, он остаётся валидным до истечения срока действия.

Причина: отсутствие архитектуры refresh-токенов и стратегии ротации.


Отсутствие проверки подписи

Иногда разработчики просто декодируют JWT, не проверяя подпись. Это полностью нарушает модель безопасности, так как любой может изменить payload.

Причина: использование методов decode вместо verify или misunderstanding API библиотеки jose.


Неверная обработка ошибок верификации

Ошибки верификации (например, неверная подпись или истёкший токен) могут игнорироваться или обрабатываться некорректно. В некоторых случаях приложение продолжает работу, даже если токен невалиден.

Причина: недостаточная обработка исключений и отсутствие строгой логики отказа.


Использование одного ключа для разных целей

Один и тот же ключ может использоваться для подписи, шифрования и в разных сервисах. Это нарушает принцип разделения ответственности и увеличивает риск компрометации.

Причина: упрощение инфраструктуры за счёт безопасности.


Неправильная работа с JWK и JWKS

При использовании набора ключей (JWKS) ошибки возникают в следующих случаях:

  • кеширование ключей без обновления
  • отсутствие проверки kid
  • выбор неправильного ключа для верификации

Это может привести к невозможности проверки токена или использованию устаревшего ключа.

Причина: сложность работы с динамическими ключами и отсутствие механизма обновления.


Несогласованность времени между системами

JWT сильно зависит от временных меток (iat, nbf, exp). Если серверы имеют разное системное время, валидный токен может считаться недействительным.

Причина: отсутствие синхронизации времени (например, через NTP).


Передача JWT через небезопасные каналы

JWT может передаваться:

  • через URL
  • в открытых HTTP-запросах
  • в логах

Это делает его уязвимым к перехвату.

Причина: неправильное понимание безопасных способов передачи токенов (например, через HTTPS и заголовки Authorization).


Хранение JWT в небезопасных местах на клиенте

Часто JWT сохраняется в localStorage, что делает его доступным для XSS-атак. Более безопасный вариант — использование httpOnly cookie.

Причина: удобство разработки и недостаточное внимание к клиентской безопасности.


Слишком большой payload

JWT не предназначен для хранения большого объёма данных. Перегруженный payload:

  • увеличивает размер запросов
  • замедляет обработку
  • повышает риск утечки данных

Причина: попытка использовать JWT как универсальное хранилище состояния.


Отсутствие механизма отзыва токенов

JWT по своей природе статичен: после выпуска его нельзя “отозвать”, если не реализован дополнительный механизм (черный список, short-lived токены).

Причина: архитектурное ограничение JWT и отсутствие дополнительной логики на сервере.


Неверная работа с библиотекой jose

Ошибки, специфичные для jose:

  • неправильное использование функций jwtVerify и SignJWT
  • игнорирование опций верификации (issuer, audience, clockTolerance)
  • некорректная работа с ключами в формате JWK

Причина: поверхностное изучение API библиотеки и отсутствие тестирования крайних случаев.


Использование JWT там, где он не нужен

JWT применяется даже в случаях, где достаточно сессий на сервере. Это усложняет архитектуру без реальной необходимости.

Причина: следование трендам без анализа требований.


Отсутствие логирования и мониторинга

Без логирования невозможно отследить:

  • попытки подделки токенов
  • ошибки верификации
  • подозрительную активность

Причина: недооценка важности наблюдаемости системы.


Ошибки при кодировании Base64URL

Некорректная работа с Base64URL может привести к невозможности корректного декодирования токена. Например, использование стандартного Base64 вместо URL-safe варианта.

Причина: различия в стандартах кодирования и ручная обработка токена вместо использования библиотеки.


Игнорирование стандартов RFC

JWT описан в RFC 7519 и связанных документах. Отклонение от стандарта приводит к несовместимости и уязвимостям.

Причина: реализация “на глаз” без изучения спецификации.


Неправильная работа с вложенными токенами (JWE + JWS)

При использовании зашифрованных токенов (JWE) внутри подписанных (JWS) возможны ошибки порядка операций:

  • сначала подпись, потом шифрование
  • или наоборот — в зависимости от требований

Причина: сложность комбинирования криптографических операций.


Отсутствие тестирования безопасности

JWT-интеграции редко покрываются тестами на безопасность:

  • подмена подписи
  • изменение payload
  • использование просроченных токенов

Причина: фокус на функциональности вместо безопасности.


Некорректная работа с middleware

В серверных приложениях middleware может:

  • пропускать запросы без токена
  • неправильно извлекать токен из заголовков
  • не обрабатывать ошибки

Причина: неправильная интеграция JWT-проверки в цепочку обработки запросов.


Переоценка безопасности JWT

JWT не является “серебряной пулей”. Он не защищает от:

  • XSS
  • CSRF (при неправильной реализации)
  • утечки токенов

Причина: неверное представление о возможностях технологии.