Белый список алгоритмов в Jose

Белый список алгоритмов в jose — это механизм контроля криптографических алгоритмов, которые разрешены при проверке и создании JWT (JWS/JWE). Его задача заключается в предотвращении атак, основанных на подмене алгоритма или выборе небезопасных параметров подписи и шифрования.

Формат JOSE допускает указание алгоритма прямо в заголовке токена:

{
  "alg": "HS256",
  "typ": "JWT"
}

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

  • вместо асимметричного алгоритма используется симметричный (например, RS256 → HS256)
  • применяется слабый или устаревший алгоритм
  • происходит попытка использования none-алгоритма без подписи

Белый список алгоритмов исключает подобные сценарии, фиксируя допустимые значения независимо от входящего токена.

Природа атак, связанных с alg

Подмена алгоритма (algorithm confusion)

Одна из классических атак возникает, когда сервер поддерживает несколько алгоритмов. Например:

  • ожидается RS256 (RSA + SHA-256)
  • злоумышленник меняет alg на HS256
  • публичный RSA-ключ интерпретируется как HMAC-секрет

При отсутствии ограничения список допустимых алгоритмов превращается в точку компрометации.

Использование none

Исторически некоторые реализации JWT позволяли использовать:

{
  "alg": "none"
}

Это означало отсутствие подписи. При неправильной настройке сервер мог принять такой токен как валидный.

Белый список алгоритмов в JOSE

В современных реализациях JOSE контроль алгоритмов реализуется через явное указание допустимых значений при проверке токена.

Базовый принцип

Любой входящий токен проверяется только в рамках заранее заданного списка:

  • HS256, HS384, HS512
  • RS256, RS384, RS512
  • ES256, ES384, ES512
  • EdDSA

Любые другие значения автоматически отклоняются, даже если они присутствуют в заголовке токена.

Реализация в библиотеке JOSE

В библиотеке JOSE контроль алгоритмов осуществляется через параметры функций проверки JWT.

Пример проверки JWT с ограничением алгоритмов

import { jwtVerify, createRemoteJWKSet } from 'jose'

const JWKS = createRemoteJWKSet(new URL('https://example.com/.well-known/jwks.json'))

const { payload, protectedHeader } = await jwtVerify(token, JWKS, {
  algorithms: ['RS256']
})

Ключевой параметр:

algorithms: ['RS256']

Любой токен с другим alg будет отклонён до проверки подписи.

Жёсткое ограничение при работе с несколькими алгоритмами

В некоторых системах допускается несколько алгоритмов, но список остаётся фиксированным:

const { payload } = await jwtVerify(token, JWKS, {
  algorithms: ['RS256', 'ES256']
})

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

Белый список при создании токенов

При генерации JWT алгоритм также задаётся явно, без зависимости от внешних параметров:

import { SignJWT } from 'jose'

const token = await new SignJWT({ userId: 123 })
  .setProtectedHeader({ alg: 'RS256' })
  .setIssuedAt()
  .setExpirationTime('2h')
  .sign(privateKey)

Здесь алгоритм фиксируется на уровне кода, что исключает случайную подмену.

Работа с JWE (шифрование)

В случае JWE (JSON Web Encryption) применяется аналогичный принцип ограничения алгоритмов:

import { compactDecrypt } from 'jose'

const { plaintext } = await compactDecrypt(jwe, privateKey, {
  keyManagementAlgorithms: ['RSA-OAEP-256'],
  contentEncryptionAlgorithms: ['A256GCM']
})

Контроль разделён на два уровня:

  • keyManagementAlgorithms — управление ключами
  • contentEncryptionAlgorithms — шифрование содержимого

Внутренние механизмы проверки

JOSE реализует проверку алгоритма до криптографических операций:

  1. Чтение заголовка JWT
  2. Извлечение значения alg
  3. Сравнение с белым списком
  4. Отклонение токена при несовпадении
  5. Только затем — проверка подписи

Это важно: даже корректно подписанный токен не будет принят, если алгоритм не разрешён.

Частые ошибки при настройке

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

jwtVerify(token, JWKS)

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

Доверие к alg из токена

Использование значения из заголовка без проверки:

// антипаттерн
const alg = decoded.header.alg

Смешивание симметричных и асимметричных алгоритмов

Одновременная поддержка HS256 и RS256 в одном контексте увеличивает риск атак через подмену ключей.

Рекомендации по формированию белого списка

Минимизация набора алгоритмов

Допустимые алгоритмы должны быть ограничены только необходимыми:

  • RS256 — наиболее распространённый вариант для JWT
  • ES256 — компактная альтернатива RSA
  • EdDSA — современный высокопроизводительный вариант

Исключение legacy-алгоритмов

Следует избегать:

  • HS1 / SHA-1 вариантов
  • устаревших RSA с короткими ключами
  • любых нестандартных расширений

Разделение контекстов

Разные типы токенов должны использовать разные политики:

  • access tokens — строго RS256/ES256
  • refresh tokens — отдельный набор или отдельный ключевой контур
  • внутренние сервисные токены — изолированный алгоритмический набор

Поведение при ошибке алгоритма

При несовпадении алгоритма JOSE генерирует ошибку валидации до криптографической проверки. Типичные сценарии:

  • JOSEAlgNotAllowed
  • JWSInvalid: Invalid Compact JWS

Это поведение предотвращает утечку информации о ключах и снижает поверхность атаки.

Итоговая модель безопасности

Белый список алгоритмов формирует фиксированную границу доверия:

  • входящий токен не определяет криптографическую схему
  • схема задаётся исключительно на стороне сервера
  • любые отклонения приводят к немедленному отказу

Такой подход устраняет класс атак, связанных с подменой alg, и делает обработку JWT предсказуемой и устойчивой к внешнему влиянию.