Честная проверка JWT
Задание 1Введение
Цель: Правильно проверять JWT и закрывать известные атаки на них.
Напишите функцию verify_jwt(token, secret). Если токен корректен, подписан алгоритмом HS256 и подпись совпадает — верните payload (словарь/объект). Во всех остальных случаях (битый токен, alg: none, другой алгоритм, подменённый payload) — верните None / null.
Это защита от реальных атак на JWT: не доверяйте полю alg и сравнивайте подписи за постоянное время.
Задание 2Теория и инструменты
Классические атаки: alg: none (подпись отсутствует, а сервер всё равно принимает), подмена алгоритма, подмена payload.
Правильная проверка: алгоритм фиксирован на сервере, подпись пересчитывается и сравнивается за постоянное время.
Инструменты
- Python:
hmac.new,hmac.compare_digest,base64.urlsafe_b64decode - JS:
crypto.createHmac,crypto.timingSafeEqual,Buffer.from(x, 'base64url')
Больше теории — в разделе «Обучение: Защита (код)».
Задание 3Практика: напишите код
Примеры
verify_jwt("eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VyIjoiYWxpY2UiLCJyb2xlIjoiYWRtaW4ifQ.k14AfigcGwn7KcrYv9zUyP1Dy2Sf2rd2IlCirWs6sk8", "s3cr3t-k3y")
→ {"role": "admin", "user": "alice"}verify_jwt("eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VyIjoiYWxpY2UiLCJyb2xlIjoiYWRtaW4ifQ.k14AfigcGwn7KcrYv9zUyP1Dy2Sf2rd2IlCirWs6sk8", "wrong")
→ nullverify_jwt("eyJhbGciOiJub25lIiwidHlwIjoiSldUIn0.eyJ1c2VyIjoiYWxpY2UiLCJyb2xlIjoiYWRtaW4ifQ.", "s3cr3t-k3y")
→ nullЕщё 5 скрытых тестов.
Пошаговый план — открывайте по одному шагу
- 1Разбейте токен на три части. Если частей не три —
None. - 2Раскодируйте заголовок (добавьте
=до длины, кратной 4) и проверьте, чтоalg == 'HS256'. - 3Пересчитайте подпись от
header.payloadи сравните с третьей частью через безопасное сравнение. - 4Только после этого раскодируйте и верните payload.
- 5Любое исключение —
None.
Подсказки — каждая до решения стоит −50 очков
Задание 4Как защититься
Используйте проверенные библиотеки с явным списком алгоритмов: jwt.decode(token, key, algorithms=['HS256']).
Разборы участников
Разборы открываются после того, как вы решите комнату, — чтобы не спойлерить ответ.