單例模式的反射漏洞和反序列化漏洞代碼實(shí)例
除了枚舉式單例模式外,其余4種在單例模式提到的單例模式的實(shí)現(xiàn)方式都存在反射漏洞和反序列化漏洞。
package singleton; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.ObjectInputStream; import java.io.ObjectOutputStream; import java.lang.reflect.Constructor; /** * 用反射和反序列化的方法破解單例模式 * @author weiyx15 * */ public class SingletonCrack { public static void main(String[] args) throws Exception { // 正常創(chuàng)建單例對(duì)象 SingletonLazy s1 = SingletonLazy.getInstance(); SingletonLazy s2 = SingletonLazy.getInstance(); System.out.println(s1); System.out.println(s2); // 用反射破解單例 Class<SingletonLazy> cls = (Class<SingletonLazy>) Class.forName("singleton.SingletonLazy"); // 獲取SingletonLazy類(lèi) Constructor<SingletonLazy> cons = cls.getDeclaredConstructor(null); // 獲取SingletonLazy的構(gòu)造方法 cons.setAccessible(true); // 跳過(guò)方法的可見(jiàn)性檢查 SingletonLazy s3 = cons.newInstance(); // 調(diào)用構(gòu)造方法生成新對(duì)象 SingletonLazy s4 = cons.newInstance(); // 調(diào)用構(gòu)造方法生成新對(duì)象 System.out.println(s3); System.out.println(s4); // 用反序列化破解單例 FileOutputStream fos = new FileOutputStream("object.out"); // 文件輸出流 ObjectOutputStream oos = new ObjectOutputStream(fos); // 對(duì)象輸出流 oos.writeObject(s1); // 向文件序列化對(duì)象 oos.close(); // 關(guān)閉對(duì)象輸出流 fos.close(); // 關(guān)閉文件輸出流 FileInputStream fis = new FileInputStream("object.out"); // 文件輸入流 ObjectInputStream ois = new ObjectInputStream(fis); // 對(duì)象輸入流 SingletonLazy s5 = (SingletonLazy) ois.readObject(); // 從文件反序列化對(duì)象 ois.close(); // 關(guān)閉對(duì)象輸入流 fis.close(); // 關(guān)閉文件輸入流 System.out.println(s5); } }
運(yùn)行結(jié)果
singleton.SingletonLazy@15db9742 // s1
singleton.SingletonLazy@15db9742// s2
singleton.SingletonLazy@6d06d69c// s3
singleton.SingletonLazy@7852e922// s4
singleton.SingletonLazy@3b07d329 // s5
從運(yùn)行結(jié)果可以看到,通過(guò)反射可以得到私有構(gòu)造方法,從而實(shí)例化兩個(gè)不同的對(duì)象實(shí)例 codesingleton.SingletonLazy@6d06d69c}和{@code singleton.SingletonLazy@7852e922}. 通過(guò)反序列化,也可以得到新對(duì)象{@code singleton.SingletonLazy@3b07d329}.
以懶漢式單例模式的實(shí)現(xiàn)為例,解決反射漏洞和反序列化漏洞的方法如下:
package singleton; import java.io.ObjectStreamException; import java.io.Serializable; /** * 排除了反射漏洞和反序列化漏洞的懶漢式單例模式 * @author weiyx15 * */ public class SingletonLazySafe implements Serializable{ private static SingletonLazySafe instance; private SingletonLazySafe() { // 防止反射漏洞通過(guò)再次調(diào)用私有構(gòu)造方法實(shí)例化新的instance if (instance != null) { throw new RuntimeException(); // 拋出運(yùn)行時(shí)異常 } } public static synchronized SingletonLazySafe getInstance() { if (instance == null) // 如果未實(shí)例化,則先實(shí)例化 { instance = new SingletonLazySafe(); // 調(diào)用getInstance方法后再實(shí)例化對(duì)象 } return instance; } /** * 從I/O流讀取對(duì)象時(shí)會(huì)調(diào)用readResolve接口 * 在readResolve接口中直接返回instance對(duì)象 * 避免反序列化時(shí)重新實(shí)例化對(duì)象 * @return 單例對(duì)象 * @throws ObjectStreamException */ private Object readResolve() throws ObjectStreamException { return instance; } }
以上所述是小編給大家介紹的單例模式的反射漏洞和反序列化漏洞詳解整合,希望對(duì)大家有所幫助,如果大家有任何疑問(wèn)請(qǐng)給我留言,小編會(huì)及時(shí)回復(fù)大家的。在此也非常感謝大家對(duì)腳本之家網(wǎng)站的支持!
相關(guān)文章
Maven Plugins報(bào)錯(cuò)的解決方法
本文主要介紹了Maven Plugins報(bào)錯(cuò)的解決方法,文中通過(guò)圖文介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2024-02-02idea將maven項(xiàng)目改成Spring boot項(xiàng)目的方法步驟
這篇文章主要介紹了idea將maven項(xiàng)目改成Spring boot項(xiàng)目的方法步驟,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2020-09-09使用idea的database模塊繪制數(shù)據(jù)庫(kù)er圖的方法
這篇文章主要介紹了使用idea的database模塊繪制數(shù)據(jù)庫(kù)er圖,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2021-07-07Java使用@Validated注解進(jìn)行參數(shù)驗(yàn)證的方法
這篇文章主要介紹了Java使用@Validated注解進(jìn)行參數(shù)驗(yàn)證的方法,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2019-08-08Java中有界隊(duì)列的飽和策略(reject policy)原理解析
這篇文章主要介紹了Java中有界隊(duì)列的飽和策略(reject policy)原理解析,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2020-04-04關(guān)于springboot中對(duì)sqlSessionFactoryBean的自定義
這篇文章主要介紹了springboot中對(duì)sqlSessionFactoryBean的自定義方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2021-12-12CMD運(yùn)行Intellij Idea編譯后的class文件操作
這篇文章主要介紹了CMD運(yùn)行Intellij Idea編譯后的class文件操作,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2021-02-02