
jackson-databind 2026 年 11 件のセキュリティアドバイザリ点検:ソースコードのアノテーションを走査してノイズを除去し、実際に該当する件数を判定。各アドバイザリの積集合を求めて、実際に十分なバージョン(2.18.9/2.21.5/3.1.5。advisory 上で最も一般的な 2.21.4 ではない)を特定 CVE-2026-54515 / CVE-2026-54512
jackson-databind 2026 年の 11 件のセキュリティアドバイザリを自己診断するツール。ゼロ依存の単一 jar、オフラインで動作。
Dependabot では答えられない2つの問いに答えます:
@JsonView / ポリモーフィック型 / 大文字小文字を区別しないマッチ……)を探し、「影響を受けるバージョンをインストールしている」という情報を「実際にその機能を使っている」という事実にノイズを削減します。java -jar jackson-check.jar ./target ./src
2026 年の 11 件のうち、8 件が修正バージョンとして 2.21.4 / 2.18.8 / 3.1.4 を記載しています。それに従ってアップグレードした人は、修正済みだと思い込んでいます。
実際に1件ずつ積集合を求めた答えは:
目標を押し上げているのはこの3件です:
CVE-2026-54515 —— 大文字小文字を区別しないデシリアライズでプロパティ単位の @JsonIgnoreProperties をバイパス
CVE-2026-59889 —— @JsonView が @JsonUnwrapped コンテナプロパティに対して無効
🔴 GHSA-mhm7-754m-9p8w —— CVE 番号なし。アドバイザリ本文にこうあります:
the fix was never backported to 2.21 or 2.18 … Users on 2.21.4 and 2.18.8 who upgraded per the published advisories remain vulnerable
これはパッチの欠落です:3.x 系では修正されたのに、2.18 / 2.21 系へのバックポートが漏れています。CVE 番号がないため、CVE 番号で検索してもヒットしません。
実行すればすぐ分かります:
# すでに 2.21.4 にアップグレードしたプロジェクト
java -jar jackson-check.jar ./lib ./src
# Dependabot が知らせる件数:3 件
# 🔥 注意:アドバイザリで最も多く登場する修正バージョンに上げた場合、以下の 3 件に引き続き該当します
| 座標 | Maven Central で実際に公開されているもの |
|---|---|
com.fasterxml.jackson.core:jackson-databind | 2.x のみ |
tools.jackson.core:jackson-databind | 3.x のみ |
一方、アドバイザリの構造化フィールドでは:
com.fasterxml.jackson.core に 3.x の範囲が 6 件ぶら下がっており、修正バージョン 3.1.4 はその座標では HTTP 404tools.jackson.core に 2.x の範囲が 1 件ぶら下がっており、修正バージョン 2.21.4 も同様に HTTP 404アドバイザリをそのままコピーしたツールは、存在しないものをインストールさせようとします。 本ツールは判定テーブル生成時に1件ずつ HEAD リクエストで取得可能性を実測し、取得できないものはレポート内で明示し、アップグレード推奨としては出力しません。
2つの座標の artifactId と jar ファイル名は完全に同一で、META-INF でしか区別できません —— そのため本ツールはファイル名ではなく座標で判定します。
同じ 2.18.5 でも、2つのコードで結果はまったく異なります:
ポリモーフィック型 + @JsonView を使ったコード → Dependabot は 7 件報告、実際に該当するのは 6 件
ObjectMapper を new しただけのコード → Dependabot は 7 件報告、実際に該当するのは 0 件
両方向を明確にしなければなりません。片方だけを語るのは誤解を招きます:
①「トリガー条件が見つからない」は安全を意味しない。 次の3つのケースで、それは偽りの安心になります:
ObjectMapper.addMixIn)などの実行時手段で追加されている場合、ソースコードにその語自体が存在しない;②「トリガー条件がすべて成立」も、実際に該当することの確認にはならない。 マーキングはコードベース全体を対象に集約されており、同じクラスや同じフィールドを対象にしているわけではありません。たとえば、あるエントリが @JsonView と @JsonUnwrapped を同じプロパティに付与することを要求している場合でも、このツールは両方の語がコード内に出現したことしか確認できません。
本ツールはテキストマッチのみを行い、AST 解析は行いません。 これは意図的なトレードオフです:クリティカルパスは人間が読んで自分で検証できなければならない —— 理解できない AST の判定が誤っていたときに、誰も気づけません。
バージョン判定(第1ステップ)は厳密です。トリガー条件の判定(第2ステップ)は優先順位付けにのみ使い、リスク免除には使いません。
Dependabot の盲点について:今回の 11 件には1件もありません。 公式リポジトリのアドバイザリページは 11 件、2つの座標で逆引きした合計も 11 件、差分は 0 —— これは2つのソースを確認した上で出した結論であり、1つのソースだけを見た場合のデフォルト値ではありません(tools/gen_rules.py の ASSERT2 が再実行のたびに再検証します)。つまり、今回の Dependabot のバージョン警告は正確であり、本ツールの価値はノイズ削減と積集合の算出にあり、欠落の補完ではありません。
java -jar jackson-check.jar <パス...> [オプション]
<パス> jar / war / ディレクトリ。ディレクトリはビルド成果物(バージョン判定用)と .java ソース(トリガー条件判定用)の両方を探します
--src <パス> ソースディレクトリを追加指定
--no-src ソースをスキャンしない(バージョンのみで判定、粒度は Dependabot と同等)
--all 該当しなかったエントリも一覧表示
-v, --version バージョン表示
-h, --help ヘルプ表示
終了コード:0 = バージョン非該当 · 2 = バージョン該当だがソース内にトリガー条件が見つからない(またはソース未スキャン)· 3 = トリガー条件も成立。CI でそのまま使えます。
認識できる形式:通常の jar、Spring Boot fat jar(BOOT-INF/lib/)、従来の WAR(WEB-INF/lib/)、宿主 jar に shade された jackson(依存座標は見えませんが META-INF/maven は残っています)。
# Maven プロジェクト
mvn package && java -jar jackson-check.jar target src
# 完成した jar のみの場合
java -jar jackson-check.jar app.jar
# Gradle プロジェクト
java -jar jackson-check.jar build/libs src/main/java
Java 17+ が必要です。実行時依存はゼロ —— 特に jackson 自体に依存しません。
tools/gen_rules.py は2つの一次ソースから CveTable.java を生成します:
/repos/FasterXML/jackson-databind/security-advisories —— メンテナが公開したエントリの全集 + 説明原文/advisories?ecosystem=maven&affects=<座標> —— Dependabot が実際に使う座標インデックス(2つの groupId をそれぞれ1回ずつ照会)11 件のアドバイザリは 37 件の「アドバイザリ × 座標 × バージョン範囲」ルールに展開され、13 件のアサーションが付属します。いずれかが満たされなければ処理を中止してファイルを書き出しません —— 「解析失敗で空のテーブルが生成されてもテストがすべてグリーンになる」事態を防ぎます:
python tools/gen_rules.py # ログイン済みの gh CLI が必要
56 個のユニットテスト + 7 個の実バイナリによる E2E シナリオ(実 jar:2.13.0 / 2.18.5 / 2.21.2 / 2.21.4 / 2.21.5 / 3.1.2 / 3.1.5)。
Apache-2.0
| メンテナンスブランチ | アドバイザリで最も多いもの | 実際に必要なバージョン |
|---|
| 2.18.x | 2.18.8 | 2.18.9 |
| 2.21.x | 2.21.4 | 2.21.5 |
| 2.22.x | — | 2.22.1 |
| 3.1.x | 3.1.4 | 3.1.5 |
| 3.2.x | — | 3.2.1 |
| トリガー条件 | 関連エントリ |
|---|
@JsonView | CVE-2026-54517 / 54518 / 59889 / GHSA-mhm7 |
@JsonTypeInfo / activateDefaultTyping / PolymorphicTypeValidator | CVE-2026-54512 / 54513 |
@JsonIgnoreProperties + ACCEPT_CASE_INSENSITIVE_PROPERTIES | CVE-2026-54515 |
@JsonIgnore + @JsonProperty リネーム | CVE-2026-54516 |
Java Record + PropertyNamingStrategy + @JsonIgnore | CVE-2026-59888 |
InetSocketAddress フィールド | CVE-2026-54514 |
readTree() + JsonNode.toString() | CVE-2026-50193 |
| アサーション | 確認内容 |
|---|
| ASSERT2 | ⭐ 2つのソースの盲点比較。差分は 0 であるか、1件ずつ説明される必要がある |
| ASSERT7 | 各修正バージョンを1件ずつ HEAD リクエストして Maven Central での取得可能性を確認 |
| ASSERT8 | 双方向のゴースト確認:maven-metadata.xml を取得して、その座標に該当メジャーバージョン系全体が存在しないことを証明 |
| ASSERT9 | ブランチごとに積集合を求め、同じブランチ内の最低修正バージョンより本当に高いことを確認 |
| ASSERT11 | 各トリガー条件のアンカー文字列が公式説明原文に一字一句含まれている必要がある |
| ASSERT12 | すべてのエントリに CVSS スコアが必要(2つのソースの和集合) |
| 番号 | 深刻度 | テーマ |
|---|
| CVE-2026-54512 | high 8.1 | PolymorphicTypeValidator のジェネリクス引数バイパス |
| CVE-2026-54513 | high 8.1 | allowIfSubTypeIsArray() 配列サブタイプの allowlist バイパス |
| CVE-2026-50193 | medium 7.5 | 深くネストした JsonNode.toString() によるスタックオーバーフロー |
| CVE-2026-54514 | medium 5.3 | InetSocketAddress のデシリアライズによる DNS トリガー(SSRF) |
| CVE-2026-54515 | medium 5.3 | 大文字小文字を区別しない再構築で @JsonIgnoreProperties をオーバーライド |
| CVE-2026-54516 | medium 5.3 | リネームされた @JsonIgnore setter でもプライベートフィールド経由で書き込める |
| CVE-2026-54517 | medium 5.3 | @JsonView が setterless creator プロパティに対して無効 |
| CVE-2026-54518 | medium 6.5 | @JsonView が unwrapped creator 引数に対して無効 |
| CVE-2026-59888 | medium 6.5 | Record プロパティの @JsonIgnore が命名戦略でバイパスされる |
| CVE-2026-59889 | medium 6.5 | @JsonView が @JsonUnwrapped コンテナプロパティに対して無効 |
| GHSA-mhm7-754m-9p8w | medium 6.5 | CVE 番号なし · @JsonView + As.EXTERNAL_PROPERTY のパッチ欠落 |