
pac4j-check v0.2.0
Scanner offline per CVE-2026-29000 (CVSS 10.0) in org.pac4j:pac4j-jwt. Ispeziona direttamente jar/fat-jar, quindi funziona dove mvn dependency:tree non può. Singolo jar, zero dipendenze, Java 8+.
pac4j-check
Scansione offline per CVE-2026-29000 (CVSS 10.0) — inclusi i pacchetti che l'advisory ufficiale non elenca.
English | 中文
Singolo jar, circa 24KB, zero dipendenze a runtime, disponibile da Java 8, completamente offline, non trasmette alcun dato.
Cos'è questa vulnerabilità
JwtAuthenticator di org.pac4j:pac4j-jwt non impone la validazione della firma durante l'elaborazione di JWT cifrati (JWE).
Un attaccante che ottiene la chiave pubblica RSA del server (la chiave pubblica è di per sé pubblica)
può costruire un PlainJWT incapsulato in un JWE, scrivendo subject e role con valori arbitrari,
autenticandosi come qualsiasi utente, inclusi gli amministratori. Senza alcuna credenziale.
| Voce | Valore |
|---|---|
| CVE | CVE-2026-29000 |
| GitHub advisory | GHSA-pm7g-w2cf-q238 |
| CVSS | 10.0 (punteggio pieno) |
| Data di pubblicazione | 2026-03-05 |
pac4j è ampiamente integrato in Spring Security, Apereo CAS, JEE, Vert.x, Play, Dropwizard e altri.
🔴 Correzione v0.2.0: l'affermazione centrale della v0.1.0 era errata
La v0.1.0 sosteneva che «il database ufficiale delle vulnerabilità elenca solo 1 pacchetto, mentre in realtà ce ne sono 5», e di conseguenza segnalava come vulnerabili
pac4j-oidc / javalin-pac4j / lagom-pac4j / ratpack-pac4j.
Erano falsi positivi. L'advisory ufficiale elenca correttamente solo pac4j-jwt.
Base della revisione (due prove indipendenti, entrambe riproducibili autonomamente):
| Artefatto | La sua dipendenza da pac4j-jwt | Viene trasmessa agli utilizzatori? |
|---|---|---|
pac4j-oidc | scope test (verificato versione per versione su 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 | quel blocco di dipendenze è interamente racchiuso in un commento XML, non esiste affatto | ❌ |
- Lo scope non si propaga — in Maven le dipendenze
test/providednon vengono trasmesse a valle, pac4j-jwt non compare nel runtime classpath degli utilizzatori. - Verifica materiale dell'artefatto —
pac4j-oidc-6.0.0.jarcontiene 78 voci, tutte sottoorg/pac4j/oidc/, senza alcuna classe pac4j-jwt inclusa tramite shade. Né trasmessa, né incorporata.
Dov'è l'errore: la v0.1.0 analizzava i pom uno per uno, ma guardava solo «chi dichiara la coordinata pac4j-jwt»,
senza considerare lo scope — scambiando «dichiarato nel pom» per «l'utilizzatore lo riceverà».
Se hai aggiornato pac4j a causa di un report della v0.1.0, quell'aggiornamento non era necessario (l'aggiornamento in sé è innocuo). È necessario intervenire solo quando nella tua applicazione è effettivamente presente una versione vulnerabile di
pac4j-jwt.
Perché serve comunque uno strumento dedicato
Per determinare se su una determinata macchina esiste davvero un pac4j-jwt vulnerabile, mvn dependency:tree fallisce in due situazioni —
su una macchina di produzione c'è solo un fat-jar già confezionato (senza sorgenti né pom); oppure è stato incluso tramite shade all'interno di un SDK,
e non compare affatto nell'albero delle dipendenze. Questo strumento analizza direttamente l'artefatto stesso, senza dipendere dall'ambiente di build.
| Artefatto | Numero di versioni vulnerabili | Advisory ufficiale |
|---|---|---|
org.pac4j:pac4j-jwt | 114 | ✅ l'unico elencato, e questo è corretto |
Utilizzo
java -jar pac4j-check.jar ./myapp.jar # scansiona un jar/war
java -jar pac4j-check.jar /opt/apps # scansiona una directory (ricorsivamente)
java -jar pac4j-check.jar /opt/apps --json # output JSON, comodo per le pipeline
java -jar pac4j-check.jar ./app.jar --gbk # da usare quando la console Windows mostra caratteri cinesi corrotti
Codici di uscita: 0 = nessuna vulnerabilità trovata · 1 = dubbio/impossibile determinare · 2 = vulnerabilità trovata. Utilizzabile direttamente in CI.
Esempio di output
[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
La v0.1.0 qui segnalava anche una riga
[CRITICAL] pac4j-oidc— era un falso positivo, rimosso nella v0.2.0, per i motivi spiegati nella correzione all'inizio.
Cosa fa
- Espande ricorsivamente i Spring Boot fat-JAR (in memoria, senza estrarre su disco), risalendo al percorso annidato specifico
- Rileva i casi di shade all'interno di un jar ospite — proprio quelli che
mvn dependency:treenon riesce a individuare - Risale alla catena di introduzione — ti dice quale artefatto ha trascinato dentro pac4j-jwt
- Fornisce un verdetto basato sugli intervalli ufficiali e un obiettivo di aggiornamento concreto
Regole di verdetto e limiti (leggere prima dell'uso)
Il verdetto si basa sempre sull'advisory ufficiale 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
Autoverifica: questo strumento esegue il verdetto su tutte le 147 versioni di pac4j-jwt presenti su Maven Central,
il numero di corrispondenze è 114, in perfetta corrispondenza con la somma delle versioni dei tre intervalli dell'advisory ufficiale (13+33+68).
Questa asserzione è scritta nei test (OfficialRangeCrossCheckTest); se non corrisponde, la build fallisce.
⚠️ Ma bisogna essere chiari su cosa verifica: verifica che l'algoritmo degli intervalli di versione sia corretto, non può verificare «quali artefatti debbano entrare nella tabella dei verdetti» — il falso positivo della v0.1.0 si verificò proprio in quest'ultimo caso, e allora questa autoverifica era verde. L'ambito coperto dalla verifica ≠ l'ambito in cui la conclusione è valida.
Due limiti che vanno dichiarati
-
Copre solo il groupId
org.pac4j. Alcune ricerche di terze parti sostengono che gli artefatti vulnerabili siano 19 in totale, per 1.020 versioni, ma non hanno pubblicato l'elenco completo. Questo strumento ricostruisce in modo indipendente la porzione relativa a org.pac4j, senza dichiarare di coprire tutto. Altri groupId (comeorg.apereo.casdi Apereo CAS) non sono inclusi. -
pac4j-jwt6.0.0 ~ 6.0.4 è contrassegnato come «dubbio» e non come «vulnerabile». La fonte ufficiale afferma che la serie 6.x è vulnerabile a partire da6.0.4.1; mentre ricerche di terze parti sostengono che la vulnerabilità fosse stata introdotta già in1.9.2— se fosse vero, anche queste 5 versioni andrebbero considerate. Non abbiamo verificato in modo indipendente le conclusioni di terze parti, quindi le segnaliamo separatamente e consigliamo un aggiornamento prudente, invece di dichiararle direttamente vulnerabili.
Perché tanta prudenza: una regola di verdetto sbagliata non è un «falso positivo», è far compiere all'utente un'azione sbagliata. Meglio contrassegnare come dubbio, piuttosto che fissare come conclusione un ambito non verificato.
Build
mvn package # 产物:target/pac4j-check.jar
mvn test # 31 个测试
Feedback
Se trovi errori di verdetto, mancate rilevazioni o falsi positivi, apri una Issue. Se riesci a fornire coordinate riproducibili dell'artefatto (groupId:artifactId:version), la correzione sarà molto più rapida.
License
Apache License 2.0
pac4j-check (English)
Scanner offline per CVE-2026-29000 (CVSS 10.0) — inclusi i pacchetti che l'advisory ufficiale non elenca.
Singolo jar, ~24KB, zero dipendenze a runtime, Java 8+, completamente offline, non invia nulla da nessuna parte.
La vulnerabilità
JwtAuthenticator in org.pac4j:pac4j-jwt non impone la validazione della firma su alcuni
percorsi di elaborazione di JWT cifrati (JWE). Un attaccante in possesso della chiave pubblica RSA del server
(che è pubblica per progettazione) può costruire un PlainJWT incapsulato in un JWE con subject e claim di ruolo arbitrari
e autenticarsi come qualsiasi utente, inclusi gli amministratori — senza credenziali.
| CVE | CVE-2026-29000 |
| GitHub advisory | GHSA-pm7g-w2cf-q238 |
| CVSS | 10.0 |
| Pubblicato | 2026-03-05 |
🔴 Correzione v0.2.0: l'affermazione centrale della v0.1.0 era errata
La v0.1.0 sosteneva che l'advisory ufficiale «elenca solo un pacchetto mentre ce ne sono cinque», e
segnalava pac4j-oidc / javalin-pac4j / lagom-pac4j / ratpack-pac4j come vulnerabili.
Erano falsi positivi. L'advisory che elenca solo pac4j-jwt è corretto.
| Artefatto | Come dichiara pac4j-jwt | Raggiunge i consumatori? |
|---|---|---|
pac4j-oidc | scope test (verificato su 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 | l'intero blocco è dentro un commento XML — non esiste | ❌ |
Due linee di prova indipendenti, entrambe riproducibili:
- Lo scope non si propaga — Maven non trasmette le dipendenze
test/providedai consumatori a valle, quindi pac4j-jwt non raggiunge mai il loro runtime classpath. - Ispezione dell'artefatto —
pac4j-oidc-6.0.0.jarha 78 voci, tutte sottoorg/pac4j/oidc/, senza classi pac4j-jwt incluse tramite shade.
Causa principale: la v0.1.0 analizzava effettivamente ogni pom, ma guardava solo chi nomina la coordinata,
mai lo scope — scambiando «dichiarato in un pom» per «raggiunge il consumatore».
Se hai aggiornato pac4j a causa di un report della v0.1.0, quell'aggiornamento non era necessario (sebbene innocuo). È necessario intervenire solo quando un
pac4j-jwtvulnerabile è effettivamente presente.
Perché uno strumento dedicato
Determinare se un pac4j-jwt vulnerabile è effettivamente presente su una determinata macchina mette in difficoltà
mvn dependency:tree in due casi comuni: una macchina di produzione con solo un fat-jar confezionato
(senza sorgenti, senza pom), oppure una copia inclusa tramite shade dentro un SDK di terze parti, invisibile all'albero
delle dipendenze. Questo strumento ispeziona gli artefatti stessi.
| Artefatto | Versioni vulnerabili | Nell'advisory ufficiale |
|---|---|---|
org.pac4j:pac4j-jwt | 114 | ✅ l'unico elencato — e questo è corretto |
Utilizzo
java -jar pac4j-check.jar ./myapp.jar
java -jar pac4j-check.jar /opt/apps
java -jar pac4j-check.jar /opt/apps --json
Codici di uscita: 0 pulito · 1 contestato/indeterminato · 2 vulnerabile.
Cosa fa
- Decomprime ricorsivamente i Spring Boot fat-JAR in memoria (nulla scritto su disco)
- Rileva pac4j-jwt incluso tramite shade in un jar ospite — il caso che
mvn dependency:treenon riesce a vedere - Traccia la catena di introduzione, così sai quale artefatto lo ha trascinato dentro
- Segnala un obiettivo di aggiornamento concreto
Regole e limiti
I verdetti seguono esattamente l'advisory ufficiale GHSA-pm7g-w2cf-q238:
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
Verifica incrociata: eseguendo le regole su tutte le 147 versioni pubblicate di pac4j-jwt si ottengono 114
vulnerabili — in perfetta corrispondenza con i tre intervalli dell'advisory (13+33+68). Questo è asserito in
OfficialRangeCrossCheckTest; una mancata corrispondenza fa fallire la build.
Due limiti, dichiarati chiaramente:
- È coperto solo il groupId
org.pac4j. Ricerche di terze parti riportano 19 pacchetti vulnerabili su 1.020 versioni ma non hanno pubblicato l'elenco completo. Questo strumento ricostruisce in modo indipendente la porzione org.pac4j e non dichiara una copertura completa. - pac4j-jwt 6.0.0–6.0.4 sono segnalate come CONTESTATE, non VULNERABILI. L'advisory fa iniziare l'intervallo
6.x da
6.0.4.1; ricerche di terze parti affermano che il difetto fu introdotto già in1.9.2. Non abbiamo verificato in modo indipendente quest'ultima affermazione, quindi queste versioni sono segnalate per revisione umana con una raccomandazione di aggiornamento prudente, invece di essere dichiarate vulnerabili.
Un verdetto sbagliato non è un "falso positivo" — fa compiere alle persone l'azione sbagliata.
License
Apache License 2.0
Serve un'indagine più approfondita?
Questo strumento risponde alla domanda «sono stato colpito o no». Alle seguenti domande non può rispondere, ma posso occuparmene io:
- La dipendenza è stata sottoposta a shade / relocate, oppure l'artefatto di build non è nemmeno ottenibile
- Bisogna determinare se «questa CVE si attiva effettivamente sulla nostra catena di chiamate», non solo se la versione corrisponde
- Serve una personalizzazione in base al vostro processo di build o al vostro ambiente di rete interno, e l'integrazione nella pipeline esistente
- Avete a che fare con un problema simile di un altro componente, per cui non esiste ancora uno strumento pronto
📮 [email protected] — descrivete la situazione, entro 24 ore vi darò una risposta scritta di una pagina: se è fattibile, dov'è la difficoltà, quanto tempo ci vorrà approssimativamente. Questo passo è gratuito e non richiede alcun impegno da parte vostra.