
Офлайн-сканер для CVE-2026-29000 (CVSS 10.0) в org.pac4j:pac4j-jwt. Проверяет jar/fat-jar напрямую, поэтому работает там, где mvn dependency:tree не может. Один jar, без зависимостей, Java 8+.
Офлайн-проверка CVE-2026-29000 (CVSS 10.0) — включая те пакеты, которые не указаны в официальном advisory.
English | 中文
Один jar, около 24KB, без runtime-зависимостей, работает начиная с Java 8, полностью офлайн, никуда не передаёт данные.
JwtAuthenticator из org.pac4j:pac4j-jwt при обработке зашифрованных JWT (JWE) не выполняет обязательную проверку подписи.
Атакующему достаточно получить RSA-публичный ключ сервера (публичный ключ и так открыт),
чтобы сконструировать обёрнутый в JWE PlainJWT, записать в subject и role произвольные значения
и войти под любым пользователем, включая администратора. Никаких учётных данных не требуется.
| Пункт | Значение |
|---|---|
| CVE | CVE-2026-29000 |
| GitHub advisory | GHSA-pm7g-w2cf-q238 |
| CVSS | 10.0 (максимум) |
| Дата публикации | 2026-03-05 |
pac4j широко интегрируется в Spring Security, Apereo CAS, JEE, Vert.x, Play, Dropwizard и другие.
v0.1.0 утверждал, что «официальная база уязвимостей перечисляет только 1 пакет, тогда как на самом деле их 5», и поэтому помечал как уязвимые
pac4j-oidc / javalin-pac4j / lagom-pac4j / ratpack-pac4j.
Это были ложные срабатывания. Официальный advisory, указывающий только pac4j-jwt, прав.
Основание для пересмотра (два независимых доказательства, оба воспроизводимы самостоятельно):
| Артефакт | Как он зависит от pac4j-jwt | Передаётся ли потребителю |
|---|---|---|
pac4j-oidc | scope test (проверено по версиям 3.0.0 / 4.0.0 / 4.5.0 / 5.0.0 / 5.7.0 / 6.0.0 / 6.3.0) | ❌ |
javalin-pac4j | scope test | ❌ |
lagom-pac4j-parent | scope provided | ❌ |
ratpack-pac4j:1.4.6 | весь этот блок зависимости завёрнут в XML-комментарий, его вообще не существует | ❌ |
test / provided не передаются вниз по цепочке,
на runtime classpath потребителя pac4j-jwt не появится.pac4j-oidc-6.0.0.jar всего 78 записей, все в org/pac4j/oidc/,
нет ни одного зашэйденного класса pac4j-jwt. Ни передаётся, ни содержится.В чём была ошибка: v0.1.0 разбирал pom за pom, но смотрел только на «кто прописал координату pac4j-jwt»,
не глядя на scope — приняв «прописано в pom» за «потребитель это получит».
Если вы обновляли pac4j из-за отчёта v0.1.0, это обновление не было обязательным (само обновление безвредно). Действия нужны только тогда, когда в вашем приложении действительно присутствует уязвимая версия
pac4j-jwt.
Определить, есть ли на конкретной машине уязвимый pac4j-jwt, с помощью mvn dependency:tree не удаётся в двух случаях —
на продакшене есть только собранный fat-jar (без исходников и pom); либо он зашэйден внутрь какого-то SDK
и в дереве зависимостей вообще не появляется. Этот инструмент сканирует сами артефакты, не полагаясь на среду сборки.
| Артефакт | Число уязвимых версий | Официальный advisory |
|---|---|---|
org.pac4j:pac4j-jwt | 114 | ✅ единственный указанный, и это правильно |
java -jar pac4j-check.jar ./myapp.jar # сканировать один jar/war
java -jar pac4j-check.jar /opt/apps # сканировать каталог (рекурсивно)
java -jar pac4j-check.jar /opt/apps --json # вывод в JSON, удобно для конвейера
java -jar pac4j-check.jar ./app.jar --gbk # при кракозябрах в китайской консоли Windows
Коды возврата: 0 = уязвимостей не найдено · 1 = спорно/невозможно определить · 2 = обнаружено уязвимое. Можно напрямую подключать к CI.
[CRITICAL] pac4j-jwt 5.4.3
位置 :demo-app.jar!/BOOT-INF/lib/pac4j-jwt-5.4.3.jar
版本来源:pom.properties(可靠)
部署形态:Spring Boot fat-JAR
结论 :命中 CVE-2026-29000 —— JWE 处理路径未强制校验签名,
拿到服务器 RSA 公钥即可伪造任意身份(含管理员)登录
处置 :升级 pac4j-jwt 至 5.7.9
В v0.1.0 здесь дополнительно выводилась строка
[CRITICAL] pac4j-oidc— это было ложное срабатывание, в v0.2.0 оно удалено, причины см. в исправлении в начале.
mvn dependency:treeОпределение всегда основывается на официальном advisory GHSA-pm7g-w2cf-q238:
pac4j-jwt < 4.5.9 -> 升 4.5.9
pac4j-jwt >= 5.0.0-RC1 且 < 5.7.9 -> 升 5.7.9
pac4j-jwt >= 6.0.4.1 且 < 6.3.3 -> 升 6.3.3
Самопроверка: инструмент прогоняет определение по всем 147 версиям pac4j-jwt в Maven Central,
число попаданий — 114, что точно совпадает с суммой версий по трём диапазонам официального advisory (13+33+68).
Это утверждение зафиксировано в тесте (OfficialRangeCrossCheckTest), при несовпадении сборка падает.
⚠️ Но важно понимать, что именно это проверяет: проверяется корректность алгоритма диапазонов версий, а не то, «какие артефакты должны входить в таблицу определения» — ложное срабатывание v0.1.0 произошло именно во втором, и тогда эта самопроверка была зелёной. Область, где проверка проходит ≠ область, где вывод верен.
Покрывается только один groupId — org.pac4j.
Сторонние исследования утверждают, что уязвимых артефактов всего 19, а версий — 1 020, но полный список не опубликован.
Этот инструмент независимо восстанавливает часть в пределах org.pac4j и не заявляет о полном покрытии.
Другие groupId (например, org.apereo.cas из Apereo CAS) не включены.
pac4j-jwt 6.0.0 ~ 6.0.4 помечены как «спорные», а не «уязвимые».
Официально заявлено, что 6.x уязвим начиная с 6.0.4.1; сторонние исследования утверждают, что уязвимость была внесена ещё в 1.9.2 —
если это так, эти 5 версий тоже должны считаться уязвимыми. Мы не проверяли выводы третьей стороны независимо,
поэтому выделяем их отдельно и рекомендуем консервативное обновление, а не выносим сразу вердикт «уязвимо».
Почему так консервативно: ошибка в правилах определения — это не «ложное срабатывание», это толчок пользователя к неверным действиям. Лучше пометить как спорное, чем зафиксировать непроверенную область как окончательный вывод.
mvn package # 产物:target/pac4j-check.jar
mvn test # 31 个测试
Обнаружили ошибку в определении, пропуск или ложное срабатывание — создайте Issue. Если вы можете предоставить воспроизводимые координаты артефакта (groupId:artifactId:version), исправление пойдёт гораздо быстрее.
Apache License 2.0
Offline scanner for CVE-2026-29000 (CVSS 10.0) — including the packages the official advisory does not list.
Single jar, ~24KB, zero runtime dependencies, Java 8+, fully offline, sends nothing anywhere.
JwtAuthenticator in org.pac4j:pac4j-jwt fails to enforce signature validation on certain
encrypted JWT (JWE) processing paths. An attacker holding the server's RSA public key
(which is public by design) can craft a JWE-wrapped PlainJWT with arbitrary subject and role
claims and authenticate as any user, including administrators — with no credentials.
| CVE | CVE-2026-29000 |
| GitHub advisory | GHSA-pm7g-w2cf-q238 |
| CVSS | 10.0 |
| Published | 2026-03-05 |