![]() |
https://forum.antichat.xyz/attachmen...1811842843.png
Как часто ты встречал JWT в своей работе? Честно? Этот стандарт так плотно вошёл в веб-приложения, что его используют везде: от API до аутентификации и микросервисов. Но если бы всё было так просто... Все эти токены на самом деле могут быть твоими врагами, если не уметь правильно с ними работать. И тут начинается настоящая проблема - ошибки в реализации JWT... Это уязвимости, которые могут привести к серьёзным последствиям: от захвата аккаунтов до эскалации привилегий и обхода авторизации. Проблема в том, что в 2026 году всё стало ещё хуже. Мы говорим не только о традиционном вебе, но и о современных микросервисах, которые только ускоряют движение атаки. JWT теперь можно использовать не только для того, чтобы обойти одну точку входа, но и перемещаться по всей архитектуре, постепенно расширяя доступ к сервисам. И это уже не просто ошибка в авторизации - это дорога к хаосу. Всё это стало возможным благодаря не всегда очевидным уязвимостям, которые, как мы знаем, всегда появляются в самых неожиданных местах. А теперь давай смотреть по-серьёзному. За этим маленьким и красивым токеном скрывается целая вселенная угроз, и если ты не знаешь, как правильно с ним работать, ты либо уже стал жертвой атаки, либо будешь ею в ближайшее время. Вопрос только в том, насколько ты готов к этому. Поехали разбираться, как можно обойти, что можно сломать и как это всё защитить. Структура JWT: Header, Payload, Signature Как бы не хотелось верить в магию, но всё, что ты видишь в JWT, сводится к трём частям. И это не просто так. Это три элемента, которые, если понять их структуру, позволят тебе не только быстро разобраться, что идёт не так, но и подстроить свой инструмент атаки или защиты. Так вот, JWT - это Header, Payload и Signature, где каждая из этих частей решает свою задачу. Header - заголовок, который скрывает всё Эта часть токена отвечает за два основных параметра: тип токена и алгоритм подписи. На самом деле ничего сверхсложного. В основном ты увидишь поле alg, которое определяет, какой алгоритм использован для подписи (например, HMAC или RSA). Это поле задаёт направление, по которому сервер будет проверять подпись. То есть если сервер ожидает определённый алгоритм, а ты, подменив его, отправишь токен с другим значением в alg, то вся проверка подписи слетит. Вот пример этого заголовка: JSON: Код:
{Payload - то, что ты скрываешь Payload - это суть токена. Тут хранятся все данные, которые сервер передаёт клиенту или которые клиент посылает на сервер. Тут может быть всё: от идентификатора пользователя до роли, срока действия токена или других специфичных данных. На этом этапе токен уже выглядит как нечто большее, чем просто случайная строка. Но в этой части, по сути, нет никакой защиты. Всё можно подделать. Например, вот так может выглядеть payload: JSON: Код:
{Signature - подпись, которая вроде как защищает, но не всегда Подпись, или Signature, должна обеспечивать проверку целостности токена и подтверждать, что данные в нём не были изменены. Тут всё, что нужно сделать - взять данные из Header и Payload, применить к ним алгоритм, который указан в заголовке, и получить подпись, зашифрованную с использованием секретного ключа. По идее, сервер должен взять этот токен, пересчитать подпись с его помощью и проверить, совпадает ли она с тем, что пришло. Если нет - всё ломается, и токен становится недействительным. Это, в принципе, весь защитный механизм. Код: Код:
..None Algorithm Attack Не всё, что блестит - золото. Так и с JWT. Вроде бы всё проверяется, всё подписи есть, но вот ты забываешь один момент, и вдруг оказываешься в очень неприятной ситуации. Алгоритм None - это как подарок для атакующего, если сервер не проверяет правильность алгоритма в заголовке. При этом токен становится валидным, даже если его подпись отсутствует. Легко понять, почему это такой больной момент. Механика: alg=none bypass Злоумышленник подменяет поле alg в заголовке на none. Почему это так эффективно? Потому что это всё, что ему нужно. Сервер, не проверяя этот момент, сразу пропустит токен, не пытаясь верифицировать его подпись. То есть ты приходишь к серверу с фальшивым токеном, он его принимает как валидный, и ты можешь использовать его, чтобы получить доступ к защищённому ресурсу. Понимаешь, какая боль? Подпись как бы есть, а её и нет, потому что алгоритм стоит none. Простой пример: JSON: Код:
{Key Confusion (Algorithm Confusion) Уязвимость с подменой алгоритма, или как её называют ещё - key confusion, позволяет атакующему использовать публичный ключ вместо секретного для алгоритма HMAC. Картинка, конечно, не самая приятная, но давай разбираться. подменаRS256 → HS256 Суть атаки проста: сервер использует алгоритм Код:
RS256Код:
HS256Если сервер не проверяет, что алгоритм действительно тот, который он ожидает, то получается забавная штука: публичный ключ, который используется для RSA, оказывается вполне себе подходящим для HMAC. И ты можешь просто подделать подпись с этим публичным ключом. Примерно так это выглядит:
Код:
RS256Использование public key как HMAC secret Представь, что ты в руках держишь публичный ключ, который сервер использует для подписи. И вот ты можешь использовать этот ключ как секрет для HMAC, не парясь о том, что ты нарушаешь все правила. Буквально. Сервер будет думать, что ты использовал корректный HMAC-секрет, но на самом деле ты просто использовал публичный ключ, который на стороне клиента был, собственно, всегда в открытом доступе. Процесс выглядит так:
Код:
RS256Не всегда это прямо очевидно, но в реальности такие атаки довольно опасны. Цитата:
ХарактеристикаRS256HS256Алгори тмRSA (публичный/приватный ключ)HMAC (секретный ключ)Тип подписиАссиметричнаяСимме тричнаяУязвимость для атакЕсли алгоритм не проверяется, возможно использование публичного ключа как секрета для HMACЕсли сервер неправильно валидирует алгоритм, то можно использовать публичный ключ как секретКак это может быть использовано?Подмена алгоритма на HS256 с использованием публичного ключаПодделать подпись, используя публичный ключ как секретный Weak Secret Attacks Секреты. Они должны быть секретами, но на деле часто оказываются такими же слабенькими, как старый пароль на почте. Вроде как их никто не должен знать, но в реальности даже секрет может быть угадан за пару минут, если он слишком простой или очень удобный. А теперь представь, что этот секрет - это тот самый ключ, который используется для подписи JWT. И если ты выбрал его неудачно, твоя безопасность начинает работать по принципу «как бы не сломали, но уязвимость где-то есть». Brute-force: hashcat mode 16500 Брутфорс, как вы все знаете, это когда злоумышленник пытается перебрать все возможные варианты. Для JWT, если ключ слишком слаб, ты даже не заметишь, как его вскроют. Для этого используют инструменты, типа hashcat, которые предназначены именно для перебора паролей или секретов. В случае с JWT можно настроить hashcat mode 16500, чтобы атаковать именно подпись в формате JWT. Как это работает?
Bash: Код:
hashcat -mКод:
aКод:
zЕсли секрет был что-то вроде «abc123» - атака может быть успешной уже через несколько минут. JWK/JKU Injection Вот тебе ещё одна трещина в системе, через которую может пролезть атакующий. JWK (JSON Web Key) и JKU (JSON Web Key Set URL) - это механизмы, с помощью которых сервер может получать публичные ключи для проверки подписи JWT. Казалось бы, всё должно быть окей, токен подписан с использованием определённого ключа, а сервер этот ключ извлекает из JWK или JKU. Но если сервер не валидирует, что за ключ он на самом деле забирает, можно натворить дел. Атакующий может внедрить собственный публичный ключ через заголовок Код:
jwkКод:
jkuEmbedded JWK attack Когда сервер использует JWK для валидации подписи, то, по сути, ему нужно верифицировать ключ, который приходит из токена. Проблема возникает, когда сервер не проверяет этот ключ на подлинность, и атакующий может вставить свой собственный. Например, если в заголовке токена присутствует параметр Код:
jwkПример: JSON: Код:
{Вот что нужно делать:
Теперь переходим ко второй части - это манипуляция с URL для Код:
jkuК примеру, вместо правильного URL для получения ключа (например, Код:
https://valid-key-server.com/.well-known/jwks.jsonПример: JSON: Код:
{Пример содержимого фальшивого JWKS, который может подставить атакующий: JSON: Код:
{Проблемы с JWK/JKU Injection УязвимостьПроблемаКак это эксплуатироватьEmbedded JWKПодмена публичного ключа внутри токенаАтакующий вставляет свой ключ в заголовок и получает контрольJKU URL ManipulationПодмена URL для получения ключаАтакующий манипулирует URL и заставляет сервер использовать свой ключ 5.3. Как защититься? Как обычно, защита от таких атак - это проверка, проверка и ещё раз проверка. Используй правильные механизмы для проверки ключей и URL:
Когда мы говорим про JWT, то помимо всего прочего, важную роль играют claims - данные, которые передаются в payload. Эти данные могут быть такими, как идентификатор пользователя ( Код:
subКод:
roleКод:
issКод:
audА теперь представь, что мы эту информацию просто подменяем. Мы можем поменять Код:
subКод:
issКод:
audSub/Role Escalation Один из самых очевидных вариантов манипуляции - это подделка поля Код:
subДругой вариант - role escalation. Например, в claims может быть указана роль пользователя, и если у нас есть доступ к токену, мы можем спокойно изменить его роль на Код:
adminПример токена: JSON: Код:
{Код:
subКод:
roleКод:
adminJSON: Код:
{Iss/Aud Confusion в Multi-Tenant Если система работает в многопользовательской среде (multi-tenant), то манипуляции с полями Код:
issКод:
audДопустим, у нас есть несколько разных пользователей или клиентов в одной системе, и каждый имеет свой собственный набор токенов, которые проверяются на основе этих данных. Но если злоумышленник манипулирует полем Код:
issКод:
audКод:
issКод:
audПример: JSON: Код:
{Код:
issКод:
audКод:
issJSON: Код:
{Код:
serviceAМанипуляции с claims Тип манипуляцииОписаниеКак это используетсяSub EscalationИзменение идентификатора пользователяДоступ к чужому аккаунтуRole EscalationПодделка роли пользователяПовышение привилегий, доступ к админ-функциямIss ConfusionИзменение поля Код:
issКод:
audКак защититься? Самое важное при защите от манипуляций с claims - это валидация. Валидировать каждый claim, особенно в многопользовательских системах, критично. Проблемы начинаются, когда сервер не проверяет правильность данных в claims, доверяя тому, что пришло в токене. Как защититься:
Цитата:
JWT - это всего лишь подписанный JSON. Не серебряная пуля, не встроенная безопасность, не автоматический контроль доступа. Всё, что он реально гарантирует, - целостность. Всё остальное - на совести архитектуры. И вот тут, честно говоря, чаще всего и начинается бардак: алгоритм принимается из header, ключ годами лежит без ротации, токен живёт вечность, claims используются как источник истины. Формально всё работает. По факту - поверхность атаки. В микросервисной среде токен перестаёт быть просто маркером сессии. Он становится частью доверительной цепочки между сервисами. Один сервис валидирует криво - и дальше по цепочке уже не проверяют. Горизонтальное перемещение, privilege escalation, доступ к чужим tenant-данным - всё это вырастает из маленьких, скучных логических упрощений. Нормальная реализация JWT - это дисциплина. Жёстко зафиксированный алгоритм. Контролируемая ротация ключей. Короткий TTL. Проверка iss, aud, role, sub не для галочки, а реально, с привязкой к backend-логике. И при необходимости - отзыв через jti. Не сложно. Просто нужно делать до конца, без компромиссов. Если смотреть на JWT как на формат - он удобный. Если смотреть на него как на часть security boundary - он требовательный. И вот от этого взгляда, по сути, и зависит, станет ли он нормальным механизмом аутентификации или тихой точкой входа для того, кто копает глубже, чем принято ожидать. |
| Время: 18:29 |