
pac4j-check v0.2.0
Offline-Scanner für CVE-2026-29000 (CVSS 10.0) in org.pac4j:pac4j-jwt. Untersucht Jars/Fat-Jars direkt, funktioniert also dort, wo mvn dependency:tree nicht funktioniert. Einzelnes Jar, keine Abhängigkeiten, Java 8+.
pac4j-check
Offline-Prüfung auf CVE-2026-29000 (CVSS 10.0) — einschließlich der Pakete, die im offiziellen Advisory nicht aufgeführt sind.
English | 中文
Ein einzelnes JAR, ca. 24 KB, keine Laufzeitabhängigkeiten, ab Java 8 verfügbar, vollständig offline, überträgt keinerlei Daten nach außen.
Was diese Schwachstelle ist
Der JwtAuthenticator von org.pac4j:pac4j-jwt erzwingt bei der Verarbeitung von verschlüsselten JWTs (JWE) keine Signaturprüfung.
Ein Angreifer muss lediglich den RSA-Public-Key des Servers kennen (der Public-Key ist ohnehin öffentlich),
kann dann ein JWE-verpacktes PlainJWT konstruieren und subject sowie Rolle auf beliebige Werte setzen,
sich als beliebiger Benutzer anmelden, einschließlich Administrator. Ohne jegliche Zugangsdaten.
| Eintrag | Wert |
|---|---|
| CVE | CVE-2026-29000 |
| GitHub advisory | GHSA-pm7g-w2cf-q238 |
| CVSS | 10.0 (Maximalwert) |
| Veröffentlichung | 2026-03-05 |
pac4j wird weit verbreitet integriert, u. a. in Spring Security, Apereo CAS, JEE, Vert.x, Play und Dropwizard.
🔴 v0.2.0-Korrektur: Die Kernaussage von v0.1.0 war falsch
v0.1.0 behauptete, „die offizielle Schwachstellendatenbank listet nur 1 Paket, tatsächlich sind es 5", und meldete
pac4j-oidc / javalin-pac4j / lagom-pac4j / ratpack-pac4j als betroffen.
Das waren Fehlalarme. Das offizielle Advisory listet zu Recht nur pac4j-jwt.
Grundlage der Überprüfung (zwei unabhängige Belege, beide selbst reproduzierbar):
| Artefakt | Seine Abhängigkeit von pac4j-jwt | Wird sie an Nutzer weitergegeben |
|---|---|---|
pac4j-oidc | test-Scope (versionsweise geprüft für 3.0.0 / 4.0.0 / 4.5.0 / 5.0.0 / 5.7.0 / 6.0.0 / 6.3.0) | ❌ |
javalin-pac4j | test-Scope | ❌ |
lagom-pac4j-parent | provided-Scope | ❌ |
ratpack-pac4j:1.4.6 | Der gesamte Block ist in einen XML-Kommentar eingeschlossen, existiert also gar nicht | ❌ |
- Scope wird nicht weitergereicht — In Maven werden
test- /provided-Abhängigkeiten nicht an nachgelagerte Projekte weitergegeben, pac4j-jwt erscheint nicht im Runtime-Classpath der Nutzer. - Überprüfung am realen Artefakt —
pac4j-oidc-6.0.0.jarenthält 78 Einträge, alle unterorg/pac4j/oidc/, keine einzige hineingeshade-te pac4j-jwt-Klasse. Weder weitergereicht noch mitgeliefert.
Wo der Fehler lag: v0.1.0 hat jede pom einzeln geparst, aber nur darauf geschaut, „wer die Koordinate pac4j-jwt nennt",
ohne den scope zu beachten — „in der pom steht es" wurde mit „der Nutzer bekommt es" verwechselt.
Falls Sie aufgrund eines v0.1.0-Berichts pac4j aktualisiert haben, war dieses Update nicht erforderlich (das Update selbst ist harmlos). Handlungsbedarf besteht nur, wenn in Ihrer Anwendung tatsächlich eine betroffene Version von
pac4j-jwtvorhanden ist.
Warum trotzdem ein spezielles Werkzeug nötig ist
Um festzustellen, ob auf einer bestimmten Maschine tatsächlich ein betroffenes pac4j-jwt vorhanden ist, versagt mvn dependency:tree in zwei Fällen —
auf Produktionsmaschinen liegt nur ein fertig gebautes Fat-JAR (ohne Quellcode und pom); oder es wurde in ein SDK hineingeshade-t,
sodass es im Dependency-Tree gar nicht auftaucht. Dieses Werkzeug scannt direkt das Artefakt selbst, unabhängig von der Build-Umgebung.
| Artefakt | Anzahl betroffener Versionen | Offizielles Advisory |
|---|---|---|
org.pac4j:pac4j-jwt | 114 | ✅ das einzige aufgeführte, und das ist korrekt |
Verwendung
java -jar pac4j-check.jar ./myapp.jar # scannt ein jar/war
java -jar pac4j-check.jar /opt/apps # scannt ein Verzeichnis (rekursiv)
java -jar pac4j-check.jar /opt/apps --json # JSON-Ausgabe, gut für Pipes
java -jar pac4j-check.jar ./app.jar --gbk # bei Zeichensatzproblemen in der Windows-Konsole
Exit-Codes: 0 = nicht betroffen gefunden · 1 = fraglich/nicht bestimmbar · 2 = betroffen gefunden. Direkt in CI einbindbar.
Beispielausgabe
[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 würde hier zusätzlich
[CRITICAL] pac4j-oidcmelden — das war ein Fehlalarm, in v0.2.0 entfernt, Begründung siehe Korrekturhinweis am Anfang.
Was es tut
- Rekursives Entpacken von Spring Boot Fat-JARs (im Speicher, ohne Entpacken auf die Festplatte), Rückverfolgung bis zum konkreten verschachtelten Pfad
- Erkennung von in den Host-JAR hineingeshade-ten Fällen — genau die Fälle, die
mvn dependency:treenicht findet - Rückverfolgung der Einführungskette — zeigt, welches Artefakt pac4j-jwt hineingezogen hat
- Liefert anhand der offiziellen Bereiche eine Bewertung und ein konkretes Upgrade-Ziel
Bewertungsregeln und Grenzen (bitte vor der Nutzung vollständig lesen)
Die Bewertung richtet sich ausschließlich nach dem offiziellen 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
Selbstprüfung: Dieses Werkzeug führt die Bewertung für alle 147 pac4j-jwt-Versionen auf Maven Central durch,
die Trefferzahl beträgt 114, was exakt mit der Summe der Versionszahlen der drei offiziellen Bereiche (13+33+68) übereinstimmt.
Diese Zusicherung ist im Test (OfficialRangeCrossCheckTest) hinterlegt; bei Abweichung schlägt der Build fehl.
⚠️ Aber man muss sich klarmachen, was damit verifiziert wird: Es wird verifiziert, dass der Versionsbereichs-Algorithmus korrekt ist, nicht aber, „welche Artefakte in die Bewertungstabelle gehören" — genau Letzteres war der Fehler in v0.1.0, und damals war diese Selbstprüfung grün. Der Bereich, in dem die Prüfung besteht ≠ der Bereich, in dem die Schlussfolgerung gilt.
Zwei zwingend zu nennende Einschränkungen
-
Es wird nur die eine groupId
org.pac4jabgedeckt. Eine Drittstudie nennt insgesamt 19 betroffene Artefakte mit 1.020 Versionen, veröffentlicht aber keine vollständige Liste. Dieses Werkzeug rekonstruiert unabhängig den Teil im Bereich von org.pac4j und erhebt keinen Anspruch auf vollständige Abdeckung. Andere groupIds (z. B.org.apereo.casvon Apereo CAS) sind nicht enthalten. -
pac4j-jwt6.0.0 ~ 6.0.4 wird als „fraglich" und nicht als „betroffen" markiert. Offiziell gilt 6.x ab6.0.4.1als betroffen; eine Drittstudie behauptet, die Schwachstelle sei bereits in1.9.2eingeführt worden — falls das zutrifft, müssten auch diese 5 Versionen dazugerechnet werden. Wir haben die Dritt-Schlussfolgerung nicht unabhängig verifiziert, daher werden sie separat ausgewiesen und ein konservatives Upgrade empfohlen, statt sie direkt als kritisch einzustufen.
Warum so konservativ: Eine falsche Bewertungsregel ist kein „Fehlalarm", sondern führt dazu, dass Nutzer das Falsche tun. Lieber als fraglich kennzeichnen, als einen nicht verifizierten Bereich als feste Schlussfolgerung festzuschreiben.
Build
mvn package # 产物:target/pac4j-check.jar
mvn test # 31 个测试
Feedback
Bei Bewertungsfehlern, übersehenen Treffern oder Fehlalarmen bitte ein Issue anlegen. Wenn Sie reproduzierbare Artefakt-Koordinaten (groupId:artifactId:version) angeben können, geht die Behebung deutlich schneller.
License
Apache License 2.0
pac4j-check (English)
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.
The vulnerability
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 |
🔴 v0.2.0 correction: v0.1.0's central claim was wrong
v0.1.0 claimed the official advisory "lists only one package while there are five", and
flagged pac4j-oidc / javalin-pac4j / lagom-pac4j / ratpack-pac4j as affected.
Those were false positives. The advisory listing only pac4j-jwt is correct.
| Artifact | How it declares pac4j-jwt | Reaches consumers? |
|---|---|---|
pac4j-oidc | test scope (verified on 3.0.0 / 4.0.0 / 4.5.0 / 5.0.0 / 5.7.0 / 6.0.0 / 6.3.0) | ❌ |
javalin-pac4j | test scope | ❌ |
lagom-pac4j-parent | provided scope | ❌ |
ratpack-pac4j:1.4.6 | the whole block is inside an XML comment — it does not exist | ❌ |
Two independent lines of evidence, both reproducible:
- Scope does not propagate — Maven does not pass
test/provideddependencies to downstream consumers, so pac4j-jwt never reaches their runtime classpath. - Artifact inspection —
pac4j-oidc-6.0.0.jarhas 78 entries, all underorg/pac4j/oidc/, with no shaded pac4j-jwt classes.
Root cause: v0.1.0 did parse every pom, but only looked at who names the coordinate,
never at scope — mistaking "declared in a pom" for "reaches the consumer".
If you upgraded pac4j because of a v0.1.0 report, that upgrade was not required (though harmless). Action is only needed when an affected
pac4j-jwtis actually present.
Why a dedicated tool
Deciding whether an affected pac4j-jwt is actually on a given machine defeats
mvn dependency:tree in two common cases: a production box with only a packaged fat-jar
(no sources, no pom), or a copy shaded inside some vendor SDK, invisible to the dependency
tree. This tool inspects the artifacts themselves.
| Artifact | Affected versions | In official advisory |
|---|---|---|
org.pac4j:pac4j-jwt | 114 | ✅ the only one listed — and that is correct |
Usage
java -jar pac4j-check.jar ./myapp.jar
java -jar pac4j-check.jar /opt/apps
java -jar pac4j-check.jar /opt/apps --json
Exit codes: 0 clean · 1 disputed/undetermined · 2 affected.
What it does
- Recursively unpacks Spring Boot fat-JARs in memory (nothing written to disk)
- Detects pac4j-jwt shaded into a host jar — the case
mvn dependency:treecannot see - Traces the introduction chain, so you know which artifact pulled it in
- Reports a concrete upgrade target
Rules and limitations
Verdicts follow the official advisory GHSA-pm7g-w2cf-q238 exactly:
pac4j-jwt < 4.5.9 -> 4.5.9
pac4j-jwt >= 5.0.0-RC1 and < 5.7.9 -> 5.7.9
pac4j-jwt >= 6.0.4.1 and < 6.3.3 -> 6.3.3
Cross-check: running the rules over all 147 published pac4j-jwt versions yields 114
affected — exactly matching the advisory's three ranges (13+33+68). This is asserted in
OfficialRangeCrossCheckTest; a mismatch fails the build.
Two limitations, stated plainly:
- Only the
org.pac4jgroupId is covered. Third-party research reports 19 affected packages across 1,020 versions but has not published the full list. This tool independently reconstructs the org.pac4j portion and does not claim full coverage. - pac4j-jwt 6.0.0–6.0.4 are reported as DISPUTED, not AFFECTED. The advisory starts the
6.x range at
6.0.4.1; third-party research states the flaw was introduced as early as1.9.2. We have not independently verified the latter, so these versions are flagged for human review with a conservative upgrade recommendation rather than asserted as vulnerable.
A wrong verdict is not a "false positive" — it makes people take the wrong action.
License
Apache License 2.0
Brauchen Sie eine weitergehende Untersuchung?
Dieses Werkzeug beantwortet die Frage „Bin ich betroffen oder nicht". Die folgenden Fragen kann es nicht beantworten, dafür können Sie mich beauftragen:
- Abhängigkeiten wurden geshade-t / relocated, oder die Build-Artefakte sind gar nicht beschaffbar
- Zu beurteilen ist, ob „diese CVE in unserer Aufrufkette tatsächlich auslösbar ist", nicht nur ein Versions-Treffer
- Anpassung an Ihren eigenen Build-Prozess oder Ihre interne Umgebung, Integration in bestehende Pipelines
- Es handelt sich um ein gleichartiges Problem bei einer anderen Komponente, für die es noch kein fertiges Werkzeug gibt
📮 [email protected] — schildern Sie die Situation, ich gebe Ihnen innerhalb von 24 Stunden eine schriftliche Antwort auf einer Seite: ob machbar, wo die Schwierigkeiten liegen, wie lange es etwa dauert. Dieser Schritt ist kostenlos, und Sie müssen sich zu nichts verpflichten.