Перейти к содержимому

Поиск по платформе

JWT: Key Confusion (RS256 to HS256) на jsonwebtoken

Express-приложение подписывает JWT через RS256 и публикует RSA публичный ключ через JWKS-эндпоинт. Функция верификации вызывает jwt.verify без явного whitelist алгоритмов — это позволяет атакующему подписать HS256-токен публичным ключом и получить admin-доступ.

Автор: Hack & Fix
Освоишь: bcrypt/argon2constant-time compareMFA
Сложно+90 XP ~65 мин nodejs
CWE-287 · A07:2021 Pro
Обложка: JWT: Key Confusion (RS256 to HS256) на jsonwebtoken Обложка: JWT: Key Confusion (RS256 to HS256) на jsonwebtoken
Задача
# JWT: подмена алгоритма (Key Confusion) ## Сценарий Сервис **DataDock** продаёт наборы данных и подписывает токены асимметрично: приватный ключ живёт только на сервере, а публичный — по стандарту, принятому в OAuth-системах, — опубликован для всех проверяющих сторон. Архитектор уверен: «публичный ключ видеть можно, подделать токен им нельзя». Ваш коллега по аудиту не согласен: если проверка подписи сама решает, каким способом проверять, публикация ключа превращается в дыру. Кто прав — и что из этого следует для админ-панели сервиса? ## Цель 1. Войдите покупателем и изучите токен в cookie: каким алгоритмом он подписан. 2. Найдите публичные эндпоинты сервиса, отдающие ключ подписи, и выясните, в каком виде сервер хранит его для проверки. 3. Подпишите собственный токен с ролью администратора, не владея приватным ключом. 4. Откройте админ-панель и получите флаг. ## Теория При симметричной подписи один и тот же секрет и ставит, и проверяет подпись. При асимметричной подписывает приватный ключ, а проверяет публичный — знание публичного ничего не даёт. Key Confusion возникает, когда верификатор допускает оба способа и выбирает способ по заголовку токена: атакующий объявляет симметричный алгоритм, и сервер начинает использовать материал публичного ключа как общий секрет. **Уязвимый паттерн:** ```js if (alg === 'RS256') { decoded = jwt.verify(token, _publicKeyPEM, { algorithms: ['RS256'] }); } else { decoded = jwt.verify(token, _publicKeyDER, { algorithms: ['HS256'] }); } ``` Публичный ключ доступен каждому, поэтому «секрет» симметричной ветки известен атакующему. Остаётся взять байты ключа в том же представлении, в каком их использует сервер, и подписать токен с нужной ролью — она, как обычно в JWT, читается из полезной нагрузки. ## Точка входа атаки `POST /login` — форма входа с полями `username` и `password`; после входа токен лежит в cookie `token`. Публичный ключ: `GET /api/public-key`. Цель — `GET /admin`. * **Пользователь:** `demo` / `demo`

Похожие лабораторные (4)

другие лабы по этой уязвимости
Обложка лабы: Брутфорс Формы Входа (Нет Rate Limiting) — Node.js Обложка лабы: Брутфорс Формы Входа (Нет Rate Limiting) — Node.js
Auth

Брутфорс Формы Входа (Нет Rate Limiting) — Node.js

Форма входа Express-приложения не ограничивает количество попыток, позволяя подобрать пароль администратора перебором по словарю.

+60 XP
Node.js Pro
Exploit Fix
Обложка лабы: Timing-атака на форму входа Обложка лабы: Timing-атака на форму входа
Auth

Timing-атака на форму входа

Обработчик входа раскрывает существование пользователей через разницу во времени ответа — bcrypt вызывается только для существующих аккаунтов.

+60 XP
Node.js Pro
Exploit Fix
Обложка лабы: JWT alg:none — обход аутентификации без подписи Обложка лабы: JWT alg:none — обход аутентификации без подписи
Auth

JWT alg:none — обход аутентификации без подписи

Сервер принимает JWT с alg:none и доверяет роли из claims — подделайте токен для получения прав администратора в SecureShop.

+60 XP
Node.js Pro
Exploit Fix
Обложка лабы: JWT: подбор слабого секрета и подделка admin-токена Обложка лабы: JWT: подбор слабого секрета и подделка admin-токена
Auth

JWT: подбор слабого секрета и подделка admin-токена

Сервер подписывает JWT слабым секретом из словаря. Получив один валидный токен, атакующий за секунды подбирает секрет по словарю офлайн, подписывает новый токен с role=admin и забирает флаг.

+60 XP
Node.js Pro
Exploit Fix