JWT: алгоритм alg:none жив в 2026, стыдно признать
Сегодня препарируем классику, которая почему-то до сих пор жива в 2026-м, хотя её должны были похоронить ещё лет десять назад. Погнали.
baseline vs реальность
По спеке RFC 7519 алгоритм none вообще-то легальный — «unsecured JWT» для доверенных каналов. Но на практике это дыра размером с админскую самоуверенность: сервер получает токен, где в хедере {"alg":"none"}, подпись пустая (строка после второй точки), и если парсер не проверяет алгоритм жёстко — токен принимается как валидный. WAF тут вообще не помощник — это приглашение на танец, а не стена.
Суть атаки простая до неприличия:
- Берёшь любой валидный JWT.
- Декодируешь header, меняешь
algнаnone(иногда прокатываетNone,NONE,nOnE— регистр не всегда проверяют). - Правишь payload — например
"role":"admin". - Кодируешь обратно, оставляешь пустую подпись:
header.payload. - Отправляешь. Профит, если библиотека дырявая.
2026 жив-здоров, детка
Вот тут официально прибиваю миф «это старьё, никто уже не наступает». Смотри, что нашел только за этот год:
| Цель | CVE | Суть дыры | Статус |
|---|---|---|---|
| MinIO (OIDC) | CVE-2026-33322 | Algorithm confusion → forge токенов, доступ к S3-кредам | Патч в марте 2026 |
| HarbourJwt | CVE-2026-23993 | Любой неизвестный alg (включая none, пустую строку) обходит проверку подписи |
Раскрыто январь 2026 |
| PyJWT | CVE-2026-48526 | Обход защиты от algorithm confusion через JWK-формат, CVSS 7.4 | Патч в PyJWT 2.13.0, май 2026 |
| Keycloak | CVE-2026-11800 | Algorithm confusion в JWT Authorization Grant flow → impersonation любого федеративного юзера | Патч, июль 2026 |
| Hono middleware | CVE-2026-27804 и др. | Middleware брал алгоритм проверки прямо из токена, а не из конфига | Q1 2026, кластер CVE |
Видишь тренд? Голый alg:none уже реже встречается напрямую в свежих либах (спасибо аллоулистам), зато мутировал в algorithm confusion — младшего брата с тем же ДНК: сервер всё ещё доверяет заголовку токена вместо того, чтобы жёстко пинить ожидаемый алгоритм на своей стороне. Классика не умирает, она просто ребрендится.
Векторы атаки и команды для боевого прогона
Держи чек-лист под Burp:
- Ручной сплойт через jwt_tool:
python3 jwt_tool.py <token> -X a
Флаг -X a — это как раз «none» alg attack, автоматом генерит форджед токен.
- Burp Suite JWT Editor extension: вставляешь токен, жмёшь «Attack» → «None Algorithm», он сам перебирает регистры (
none,None,NONE) и обрезает подпись. Идеально для тех, кто ленится руками Base64 крутить. - Ручками через Python (если хочешь понимать, что происходит под капотом)
import base64, json
header = {"alg": "none", "typ": "JWT"}
payload = {"user": "admin", "role": "superadmin"}
def b64url(d):
return base64.urlsafe_b64encode(json.dumps(d).encode()).rstrip(b'=').decode()
forged = f"{b64url(header)}.{b64url(payload)}."
print(forged)
Точка на конце — это пустая подпись. Отправляешь этот токен в Authorization: Bearer ... и смотришь, ответит ли сервер как для админа.
- Algorithm confusion (RS256→HS256): если сервер использует публичный ключ как секрет для HMAC — берёшь публичный RSA-ключ (он часто торчит наружу, например через
/jwks.jsonили.well-known), подписываешь токен как HS256 этим же ключом. Server verifies с public key, думая что это HMAC secret. Очевибаг-пантера, если библиотека не пинит алгоритм заранее.
Лайфхаки и как не спалиться на стороне защиты
Если ты по эту сторону баррикад (или сдаёшь пентест-отчёт клиенту), вот что зашивать в рекомендации:
- Всегда явно указывай allowlist алгоритмов при верификации, а не бери из хедера токена:
jwt.decode(token, key, algorithms=["RS256"]), никогда без списка. - Обновляй либы — PyJWT 2.13.0+, свежий jsonwebtoken для Node, актуальный Keycloak. CVE этого года били именно по тем, кто закостенел на старых версиях.
- Проверяй
algрегистронезависимо на стороне детекта — атакующие любятNoNejust for lulz, а некоторые парсеры сравнивают строки только в одном регистре. - Тестируй JWK confusion отдельно — это новый фронт 2026 года, старые чек-листы про голый
noneего не покрывают.
Короче, alg:none — это не мёртвый баг, это спящий 0day, который просыпается каждый раз, когда очередной джун пишет свой JWT-миддлвар «по best practices из Stack Overflow». Стыдно признавать, но реальность именно такая — 2026 год, а классика 2015-го всё ещё кормит баг-баунти хантеров.
Похожие статьи

Burp Suite 2026: расширения, которые реально ускоряют работу

gRPC пентест: когда Burp плачет, а ты нет
