
pac4j-check v0.2.0
org.pac4j:pac4j-jwt における CVE-2026-29000(CVSS 10.0)のオフラインスキャナー。jar/fat-jar を直接検査するため、mvn dependency:tree が使えない環境でも動作します。単一 jar、依存関係ゼロ、Java 8+。
pac4j-check
CVE-2026-29000(CVSS 10.0)をオフラインで調査 —— 公式 advisory が列挙していないパッケージも含む。
English | 中文
単一 jar、約 24KB、ランタイム依存ゼロ、Java 8 以降で動作、完全オフライン、データを外部に送信しません。
この脆弱性とは
org.pac4j:pac4j-jwt の JwtAuthenticator は、暗号化 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.2.0 訂正:v0.1.0 の中心的主張は誤りでした
v0.1.0 は「公式脆弱性データベースには 1 つのパッケージしか列挙されていないが、実際には 5 つある」と主張し、
そのため pac4j-oidc / javalin-pac4j / lagom-pac4j / ratpack-pac4j を危険と報告していました。
それは誤検知でした。公式 advisory が pac4j-jwt のみを列挙しているのは正しいです。
検証根拠(2 つの独立した証拠、いずれも自身で再現可能):
| 成果物 | pac4j-jwt への依存 | 利用者に伝播するか |
|---|---|---|
pac4j-oidc | test scope(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 | その依存はブロック全体が XML コメントで囲まれており、そもそも存在しない | ❌ |
- scope は伝播しない —— Maven では
test/provided依存は下流に伝播せず、 利用者の runtime classpath に pac4j-jwt は現れません。 - 成果物の実物検証 ——
pac4j-oidc-6.0.0.jarは全 78 エントリで、すべてorg/pac4j/oidc/配下にあり、 shade された pac4j-jwt クラスは一切ありません。伝播もせず、同梱もしていません。
どこが誤りだったか:v0.1.0 は pom を 1 つずつ解析しましたが、「誰が pac4j-jwt という座標を書いたか」だけを見て、
scope を見ていませんでした —— 「pom に書かれている」を「利用者が受け取る」と取り違えていました。
v0.1.0 のレポートを理由に pac4j をアップグレードした場合、そのアップグレードは必須ではありませんでした(アップグレード自体は無害です)。 アプリケーションに影響を受けるバージョンの
pac4j-jwtが実際に存在する場合にのみ、対応が必要です。
それでも専用ツールが必要な理由
あるマシン上に影響を受ける pac4j-jwt が存在するかどうかの判断は、2 つのケースで mvn dependency:tree が機能しません ——
本番機にはビルド済みの fat-jar しかない(ソースも pom もない)、あるいは何らかの SDK 内部に shade されていて、
依存ツリーにそもそも現れない。本ツールは成果物そのものを直接スキャンし、ビルド環境に依存しません。
| 成果物 | 影響を受けるバージョン数 | 公式 advisory |
|---|---|---|
org.pac4j:pac4j-jwt | 114 | ✅ 唯一列挙されている、そしてこれは正しい |
使い方
java -jar pac4j-check.jar ./myapp.jar # jar/war を 1 つスキャン
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 では削除済みです。 理由は冒頭の訂正説明を参照してください。
何をするか
- Spring Boot fat-JAR を再帰的に展開(メモリ上で、解凍してディスクに書き出さない)、具体的なネストパスまで追跡
- ホスト jar に shade されているケースを識別 —— まさに
mvn dependency:treeでは見つけられない類 - 導入チェーンを追跡 —— どの成果物が pac4j-jwt を引き込んだかを教える
- 公式の範囲に基づいて判定と具体的なアップグレード先を提示
判定ルールと境界(読んでから使用してください)
判定は一律に公式 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
自己検証:本ツールは Maven Central 上の pac4j-jwt 全 147 バージョンに対して判定を実行し、
命中数は 114 で、公式 advisory の 3 区間のバージョン数の合計(13+33+68)と正確に一致します。
この主張はテスト(OfficialRangeCrossCheckTest)に書かれており、一致しなければビルドが失敗します。
⚠️ ただし、それが何を検証しているかを明確にしてください:それはバージョン区間アルゴリズムが正しいことを検証しており、 「どの成果物を判定表に入れるべきか」は検証できません —— v0.1.0 の誤検知はまさに後者で発生し、 当時この自己検証はグリーンでした。検証が通った範囲 ≠ 結論が成立する範囲。
必ず説明すべき 2 つの限界
-
org.pac4jという 1 つの groupId のみをカバーしています。 第三者の研究によれば影響を受ける成果物は計 19 個、1,020 バージョンとされていますが、完全なリストは公開されていません。 本ツールが独立して再構築したのは org.pac4j の範囲内の部分であり、すべてをカバーしているとは主張しません。 他の groupId(例:Apereo CAS のorg.apereo.cas)は対象外です。 -
pac4j-jwt6.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)を提供していただければ、修正がずっと速くなります。
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
さらに踏み込んだ調査が必要ですか?
このツールが答えるのは「自分はやられているか」です。以下は答えられないので、私に依頼できます:
- 依存が shade / relocate されている、またはビルド成果物がそもそも入手できない
- 判定すべきは「この CVE が我々の呼び出しチェーン上で実際に発火するか」であり、単なるバージョン命中ではない
- 貴社のビルドプロセスや社内環境に合わせたカスタマイズ、既存パイプラインへの組み込み
- 手元にあるのが別のコンポーネントの同種の問題で、既成ツールがない
📮 [email protected] —— 状況を説明してください。24 時間以内に 1 ページの書面回答をお返しします: できるか、難所はどこか、概算期間。このステップは無料で、事前のコミットも不要です。