Подпись хороша лишь настолько, насколько хорош проверяющий

Подпись делает его утверждения достойными доверия, но лишь если код, проверяющий её, делает это корректно. Большинство уязвимостей JWT — не изъяны в криптографии; это проверяющие, которых можно обмануть, чтобы они приняли токены, которые должны отвергнуть. Вот те, что важны, и проверки, которые их предотвращают.

Доверие алгоритму самого токена

  • alg: none. Спецификация JWT определяет «незащищённый» токен без подписи, объявленный через {"alg":"none"}. Проверяющий, который это уважает, примет токен с подделанными утверждениями и пустой подписью. Корректный проверяющий никогда не считает none действительным для токена, который должен быть подписан.
  • Путаница алгоритмов ( в ). При RS256 токен подписывается закрытым ключом и проверяется открытым. Если проверяющий читает алгоритм из токена, а атакующий меняет заголовок на HS256, проверяющий может попытаться проверить , используя открытый ключ как секрет — значение, которым атакующий тоже владеет. Подделанный токен тогда проходит.

Единственная защита для обоих одна: проверяющий решает допустимый алгоритм, а не токен. Зафиксируйте ожидаемый алгоритм (или короткий список разрешённых) в вызове проверки и отвергайте любой другой.

Пропуск утверждений

Действительная подпись доказывает, что токен выпущен и не изменён. Она не доказывает, что токен для вас или всё ещё действителен. Корректный проверяющий также проверяет:

  • exp (срок действия) и nbf (не ранее): отвергайте просроченные или ещё не действительные токены, с малой допуском на дрейф часов.
  • aud (аудитория): подтвердите, что токен предназначался этой службе. Токен, выпущенный для службы A, не должен приниматься службой B.
  • iss (издатель): подтвердите, что он пришёл от издателя, которому вы доверяете, и выводите ключ проверки от этого издателя, а не из токена.

Пропуск этого — то, как украденный или неверно направленный токен в итоге принимается там, где не должен.

Меньшие ловушки

  • Слабые секреты HMAC. Токен HS256, подписанный коротким или угадываемым секретом, можно взломать офлайн, пока не найдётся совпадающая подпись. Используйте длинный случайный ключ.
  • Обработка kid и . Заголовок kid выбирает ключ; считайте его недоверенным вводом (его использовали для инъекции) и берите ключи только из JWKS издателя, которому доверяете.
  • Путаница декодирования с проверкой. Прочитать утверждения токена без проверки подписи и времени — не проверка. Действуйте лишь на полностью проверенном токене.

Краткая версия

Зафиксируйте алгоритм, проверяйте exp, aud и iss, используйте сильные ключи и никогда не путайте декодирование с проверкой. Инструмент JWT декодирует токен, показывает его утверждения и срок действия понятным языком и проверяет подпись HMAC по вставленному секрету, всё в вашем браузере, где токен и секрет никогда не отправляются.