jackson-databind 補丁不完整,DNS SSRF 缺口未補上
GitHub Security Advisories · 2026-09-28
上一輪為 CVE-2026-54514 打的補丁,只堵住了 InetSocketAddress 反序列化時的主動 DNS 解析,卻沒擋住同一段程式碼裡的另一條分支:InetAddress 欄位在反序列化當下仍會觸發正向 DNS 查詢,SSRF 缺口等於重新打開。這個新缺口被編為 CVE-2026-77310(GHSA-vvgp-rfg2-7rr6),GitHub Security Advisories 於 2026 年 8 月 21 日發布,9 月 28 日更新說明。
漏洞機制
CVE-2026-54514(GHSA-hgj6-7826-r7m5,2026 年 6 月 16 日發布)原本修的是 JDKFromStringDeserializer 用 new InetSocketAddress(host, port) 建構物件時,建構子本身就會做一次主動的 hostname 解析,也就是攻擊者送進來的 JSON 還沒經過應用層驗證,Jackson 就先替它查了一次 DNS。當時的修法是把建構方式換成 InetSocketAddress.createUnresolved(host, port),把解析延到真正要連線時才做。
問題出在 FromStringDeserializer.Std._deserialize() 這個 switch 陳述式裡,InetSocketAddress 和 InetAddress 是兩條並排的分支,當時只改了前者。advisory 原文寫道:「That fix did not cover the sibling java.net.InetAddress branch in the very same FromStringDeserializer.Std._deserialize() switch statement, which still calls InetAddress.getByName(value)。」只要目標欄位型別是 java.net.InetAddress,反序列化當下就會呼叫 InetAddress.getByName(value) 做一次正向 DNS 查詢。
// FromStringDeserializer.Std._deserialize() 的兩條分支
case InetSocketAddress:
// CVE-2026-54514 已修:延後解析
return InetSocketAddress.createUnresolved(host, port);
case InetAddress:
// CVE-2026-77310:仍在 deserialize 當下主動查 DNS
return InetAddress.getByName(value);效果是攻擊者可以把任意 hostname 塞進 JSON payload,讓伺服器在反序列化階段就主動對外發出 DNS 查詢。這足以構成 DNS-based SSRF / out-of-band 原語:透過 DNS callback 做頻外資料外洩,或盲測某個內部 hostname 是否能被解析,藉此摸清內網拓樸,而完全不需要驗證或使用者互動。
InetSocketAddress 和 InetAddress 之所以會在同一個 switch 陳述式裡分開處理,是因為兩者在 JDK 裡本來就是不同類別:前者多帶了 port,後者單純是位址。兩條分支共用同一段反序列化流程,卻各自呼叫不同的 JDK API,這正是補丁容易漏掉兄弟分支的典型情境——review 時只盯著被回報的那個型別,沒有連帶檢查同一支函式裡邏輯相同的另一條路徑。
受影響版本
CVE-2026-77310 影響的是 2.x 與 3.x 兩條分支各自的多個版本區間,而不是單一連續範圍,代表即使先前已經升級過 CVE-2026-54514 的修補版本,仍可能落在新的受影響區間內。
| 分支 | 受影響版本 | 修補版本 |
|---|---|---|
| 2.x | ≥ 2.0.0, < 2.18.9 | 2.18.9 |
| 2.x | ≥ 2.19.0, < 2.21.5 | 2.21.5 |
| 2.x | ≥ 2.22.0, < 2.22.1 | 2.22.1 |
| 3.x | ≥ 3.0.0, < 3.1.5 | 3.1.5 |
| 3.x | ≥ 3.2.0, < 3.2.1 | 3.2.1 |
對照舊漏洞,CVE-2026-54514 的修補版本是 2.18.8、2.21.4、3.1.4——剛好都落在 CVE-2026-77310 的受影響區間內,也就是說只把 InetSocketAddress 那條分支修好的版本,對 InetAddress 這條分支完全沒有防護力。GitHub 給出的 CVSS 分數是 5.3(中等)。
修補與緩解
目前 advisory 沒有列出額外的設定層緩解,例如 PolymorphicTypeValidator 的 denylist/allowlist 調整,唯一的修法就是升級到對應分支的修補版本。用 com.fasterxml.jackson.core:jackson-databind 且 model class 裡有欄位型別是 java.net.InetAddress(常見於 webhook 設定、健康檢查、內部服務註冊等會接收外部字串再轉成位址物件的場景)的服務,都要重新檢查依賴版本。
特別要留意的是「已經修過 CVE-2026-54514」不代表安全——如果團隊在 6 月那一輪只升級到 2.18.8、2.21.4 或 3.1.4 就沒再動,現在仍落在新公告的受影響範圍內,必須再升一次到 2.18.9、2.21.5、2.22.1、3.1.5 或 3.2.1。在升級之前,暫時的緩解是在應用層對任何會被反序列化進 InetAddress 欄位的輸入做格式白名單檢查,避免任意 hostname 直接進到 Jackson 的反序列化路徑。
受影響的典型場景是直接把外部 JSON 綁定到型別為 java.net.InetAddress 的欄位,例如接收 webhook 設定、允許清單/封鎖清單設定、或是服務註冊資訊的 DTO。只要這類欄位存在,攻擊者不需要任何額外權限,就能用一次 HTTP 請求讓伺服器對外查 DNS;排查時可以直接在程式碼裡搜尋 InetAddress 型別欄位,確認它們是否經過 Jackson 反序列化,再對照上面的版本表決定是否要升級。
原始來源:GHSA-vvgp-rfg2-7rr6(CVE-2026-77310)、GHSA-hgj6-7826-r7m5(CVE-2026-54514)