Fastjson 1.2.83 在預設 AutoType=false 下仍可觸發無需傳統 gadget 的遠端程式碼執行,已在 JDK 8/17/21/25 + Spring Boot Loader 隔離環境中重現。文章作者、來源:GCSA
摘要
在傳統 Java 反序列化漏洞防禦體系中,業界普遍存在以下認知盲區:「AutoType 預設關閉就安全」、「固定了 parseObject 的第二參數(頂層目標類型)就安全」、「排空了本地 Classpath 的反序列化 Gadget 依賴就安全」。然而,最新的技術攻防演進徹底打破了這些僥倖心理。
GCSA 全球網絡安全聯盟今日獨家發布本篇技術洞察報告。報告深入復盤了 Fastjson 1.2.83 在默認 AutoType=false 狀態下,依然可觸發無需傳統 Gadget 依賴的遠程代碼執行(RCE)的底層根因。目前,該利用技術已在 JDK 8 / 17 / 21 / 25 以及 Spring Boot Loader 隔離環境中端到端復現成功。本漏洞並非傳統的「繞過黑名單後尋找本地 Gadget」,而是直接將 Fastjson 自身的 Class 元數據探測邏輯扭轉為遠程惡意 Class 的獲取與授權通道。以下為正文
發布機構:GCSA 全球網絡安全聯盟
報告類型:獨家技術洞察 / 漏洞深度剖析報告
報告日期:2026-07-21
報告狀態:已完成原始碼審計與隔離環境複現
漏洞編號:內部研究編號 FJ-GETRESOURCE-RCE(不對應已公開 CVE)
Fastjson 1.2.83 在預設 AutoType=false 下仍可觸發無需傳統 gadget 的遠端程式碼執行,已在 JDK 8/17/21/25 + Spring Boot Loader 隔離環境中重現。建議立即啟用 SafeMode 並遷移至 Fastjson 2.x。
1. 執行摘要
Fastjson 1.2.83 的 ParserConfig.checkAutoType 會將使用者可控制的 @type 值轉換為 class 資源名,並交給當前 ClassLoader 的 getResourceAsStream:

在能夠解析絕對 URL 資源名的 fat-jar ClassLoader 環境中,攻擊者可以利用點號替換構造 http:、jar:http: 和 jar:file: URL,從攻擊端下載帶有 @JSONType 的惡意 class。Fastjson 檢測到該註解後會調用 loadClass,並在危險基類檢查和目標類型相容性檢查之前直接返回該 class。class 被實例化、初始化時即可執行任意代碼。
此利用不依賴目標 classpath 中已有的傳統反序列化 gadget,且在 Fastjson AutoType=false 的預設狀態下仍可觸發。固定 JSON.parseObject 的目標類型無法阻止執行;啟用 SafeMode 可在資源存取前阻斷正常利用路徑。
本報告已使用同一個 JSON payload 在隔離 Linux 容器中完成以下複現:

2. 漏洞評級

不建議僅憑組件版本給出統一的 CVSS 9.8:普通 AppClassLoader 是負對照,現代 JDK 完整鏈還依賴能夠解析兩種絕對 JAR URL 的 loader 和 /proc/self/fd。在滿足本報告正向環境的應用中,漏洞效果為無需認證的網絡 RCE。
3. 影響範圍與前置條件
3.1 已確認範圍
- 運行時確認:Fastjson 1.2.83
- JDK 確認:8、17、21、25
- 作業系統確認:Linux;macOS 使用 /dev/fd 也完成了 JDK 17/21/25 複現
- loader 確認:Spring Boot 2.7.18 classic loader + JDK 8;Spring Boot 3.2.0 loader + JDK 17/21/25
- API 確認:JSON.parse,以及固定頂層類型的 JSON.parseObject
3.2 版本範圍說明
外部描述中的 1.2.68–1.2.83 更適合作為已知測試範圍,而不是漏洞引入版本。源碼核對表明,決定性的 class 資源探測代碼在 1.2.67 和 1.2.68 中已經存在。本報告僅對 1.2.83 完成了完整跨 JDK 運行時驗證。
3.3 利用所需條件
1. 攻擊者可以控制傳入 Fastjson 的 JSON,且輸入中的 @type 會被解析。
2. SafeMode 未啟用。
3. 加載 Fastjson 的 ClassLoader 能把構造後的絕對資源名解析為 URL。
4. 受害進程可以連接攻擊端 HTTP 服務。
5. 現代 Linux 鏈要求 /proc/self/fd 可讀,並且 loader 能解析
jar:file:/proc/self/fd/N!...。
1. JDK 需要能夠建立正常的遠端 JAR 臨時快取;這通常意味著 JVM 臨時目錄可寫。
攻擊者不需要:
- 向目標 classpath 寫入檔案
- 目標 classpath 預裝 TemplatesImpl、JNDI、C3P0、Commons Collections 等 gadget
- 開啟 Fastjson AutoType
- 控制 JSON.parseObject 的第二個參數
4. 根因分析
4.1 使用者類型名被當作資源 URL
原始碼位置:

核心代碼:

該邏輯假設 resource 只是普通的 classpath 路徑,但未限制其協議、絕對路徑語義或來源。對於特定的 fat-jar loader,以下輸入在替換後會變成絕對 URL:

因此,getResourceAsStream 從本地元數據查詢越界,加載攻擊者可控制的網路資源。
4.2 遠端 class 的 @JSONType 被當作授權依據
Fastjson 使用自己的 ASM ClassReader 解析資源內容:

攻擊端只需讓遠端 class 帶有 Fastjson 的 @JSONType 註解,即可將 jsonType 置為 true。這裡檢查的是攻擊者提供的位元組,而不是一個已經由可信 classpath 加載的類。
4.3 jsonType 觸發實際類加載
原始碼位置:
TypeUtils.loadClass 依序嘗試顯式 loader、線程上下文 loader 和 Class.forName。在正向環境中,線程上下文 loader 會再次解析相同的絕對資源名、下載 class 並執行 defineClass。
4.4 @JSONType 早回傳以繞過後續安全檢查
原始碼位置:
- 危險基類檢查不會執行
- expectClass.isAssignableFrom(clazz) 不會執行
- 無法在 class 初始化之前阻止執行固定資料繫結類型
4.5 後綴形成失敗軟通道
原始碼位置:
4.6 SafeMode 的位置
SafeMode 檢查位於資源訪問之前:
5. 利用鏈詳解
5.1 JDK 8:直接遠端 class 加載
最短形式:
JDK 17+ 也會完成網路請求,但會拒絕內部名中的空路徑段,
5.2 現代 JDK 第一階段:下載遠端 JAR
單 payload 的首個數組元素:
JDK 17+ 隨後拒絕第一階段 jar:http://... 內部名,但 Fastjson 因 Exception 後綴繼續解析數組。
5.3 現代 JDK 第二階段:重開緩存 FD
後續候選元素:
JDK 17 的 class-load 日誌中首個命中為:
5.4 為什麼一個 payload 同時兼容 JDK 8 和現代 JDK
- JDK 8 直接接受第一階段 jar:http://... class 並執行
- 第一階段 class 執行命令後故意拋出 RuntimeException("stage-one-stop"),阻止 JDK 8 繼續嘗試無關 socket/pipe FD
- JDK 17+ 在類別初始化前因第一階段非法名稱失敗,隨後透過 Exception 軟返回進入 FD 枚舉階段
6. Reproduction Environment and Evidence
6.1 被測構件哈希
6.2 一鍵複製

期望输出:腳本會:
- 編譯受損的 fat jar;
- 生成帶 FD 專用 class 的攻擊 JAR;
- 生成一個 JSON 數組 payload;
- 在隔離的 Docker 網絡中啟動攻擊端 HTTP 服務;
- 分別啟動 JDK 8/17/21/25 受害容器;
- 檢查每個容器映射出的 /tmp/fastjson-getresource-rce。
6.3 手動生成攻擊 JAR 和 payload
6.4 透過 Burp Suite 傳送
Burp 僅負責向存在 Fastjson 解析點的受影響介面發送 JSON;攻擊 JAR 仍需由攻擊端 HTTP 服務提供。
請求模板:
如果應用使用固定頂層類型,可根據欄位結構包裝陣列,例如:
本實驗使用 JSON.parseObject(json, BoundEnvelope.class) 解析上述包裝,結果仍為 RCE-OK,並正常返回 BoundEnvelope。
6.5 關鍵邊界測試

7. 修復與緩解建議7.1 首選:遷移出 Fastjson 1.x
優先遷移至正在維護的 Fastjson 2.x,並重新驗證所有多態類型、AutoType 和相容模式設定。不要僅替換 JAR 而不做回歸測試。
7.2 立即啟用 SafeMode
代碼配置:
JVM 參數:
注意:如應用已註冊 AutoTypeCheckHandler,應同步審計或移除,因為 handler 會在 SafeMode 檢查之前執行。
7.3 限制反序列化入口
- 不要將不可信的請求直接交給 JSON.parse/JSON.parseObject
- 在閘道或應用入口拒絕任何形式的特殊類型元資料
- 僅固定頂層 Java 類型並非充分防線,因為嵌套物件仍可處理 @type,且本漏洞的 jsonType 早返回繞過相容性檢查
7.4 WAF/網關臨時規則
臨時攔截 JSON key 解碼後等於 @type 的請求,並覆蓋 URL 參數、請求體及嵌套物件。不能只搜尋明文 "@type",Fastjson lexer 會先解碼欄位名,例如:
WAF 規則只能作為緩解措施,不能取代組件升級和 SafeMode。
7.5 網絡退出與運行時加固
- 禁止業務 JVM 對非必要外部地址發起 HTTP/HTTPS 連接。
- 對應用容器實施最小網路策略。
- 在兼容性允許時限制 /proc/self/fd 暴露或使用更嚴格的容器沙箱。
- 審計 ClassLoader 對絕對 URL 資源名的處理,拒絕 http:、https:、jar:、file: 等協議形式。
- 監控 JVM 臨時目錄中的異常 jar_cache* 活動。
8. 檢測建議與 IOC
8.1 請求端特徵
重點關注解碼後的 @type 值包含:
單獨出現 Exception 不足以告警,應與協議形式、@type 和數組內連續 FD 候選組合關聯分析。
8.2 網絡端特徵
- JVM 向異常主機請求無擴展名的 JAR 或 .class
- 在同一次解析請求期間出現 1–3 次重複的 GET/HEAD
- 請求路徑中可能出現 /x、/a.class 或攻擊者自定義等價路徑
8.3 主機端特徵
- JVM 臨時目錄建立 jar_cache*
- Java 進程透過 /proc/self/fd/N 重新打開自身檔案
- class-load 日誌出現類似:
9. 結論
此漏洞並非傳統的「繞過黑名單後尋找本地 gadget」,而是將 Fastjson 自身的 class 元資料探測邏輯轉變為遠端 class 获取與授權通道。@JSONType 早返回使攻擊者提供的 class 在危險基類和類型綁定檢查之前被接受;Exception 失敗軟通道及 JDK jar:http: 臨時快取則將 JDK 8 的直接加載原語擴展至 JDK 17/21/25。
因此以下常見判斷均不成立:
- 「AutoType 默認關閉,因此安全」— 不成立
- 「固定 parseObject 第二個參數,所以安全」— 不成立
- “classpath 沒有已知 gadget,所以安全” — 不成立
- “JKD 17+ 會拒絕 http:// 內部名,所以最多只是 SSRF” — 不成立
在滿足已驗證 loader、網路和檔案描述符條件的部署中,該問題可從單個未經認證的 JSON 請求發展為真實遠端程式碼執行。應優先遷移 Fastjson 2.x,並立即啟用 SafeMode、收紧出網與 ClassLoader 資源解析邊界。
10. 附件與證據路徑
轉載及版權聲明:本報告及相关技術分析由GCSA全球網絡安全聯盟獨家發布。如需轉載,請完整保留GCSA官方出處及原始連結,並不得對報告核心觀點進行惡意篡改。
來源:GCSA全球网络安全聯盟
官網:www.gcsa.org
