這篇文章給大家分享的是有關(guān)單例模式中反射漏洞和反序列化漏洞的示例分析的內(nèi)容。小編覺得挺實(shí)用的,因此分享給大家做個(gè)參考,一起跟隨小編過來看看吧。
創(chuàng)新互聯(lián)公司長期為成百上千家客戶提供的網(wǎng)站建設(shè)服務(wù),團(tuán)隊(duì)從業(yè)經(jīng)驗(yàn)10年,關(guān)注不同地域、不同群體,并針對(duì)不同對(duì)象提供差異化的產(chǎn)品和服務(wù);打造開放共贏平臺(tái),與合作伙伴共同營造健康的互聯(lián)網(wǎng)生態(tài)環(huán)境。為平順企業(yè)提供專業(yè)的網(wǎng)站制作、成都網(wǎng)站制作,平順網(wǎng)站改版等技術(shù)服務(wù)。擁有十年豐富建站經(jīng)驗(yàn)和眾多成功案例,為您定制開發(fā)。
除了枚舉式單例模式外,其余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); // 用反射破解單例 Classcls = (Class ) Class.forName("singleton.SingletonLazy"); // 獲取SingletonLazy類 Constructor cons = cls.getDeclaredConstructor(null); // 獲取SingletonLazy的構(gòu)造方法 cons.setAccessible(true); // 跳過方法的可見性檢查 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é)果可以看到,通過反射可以得到私有構(gòu)造方法,從而實(shí)例化兩個(gè)不同的對(duì)象實(shí)例 codesingleton.SingletonLazy@6d06d69c}和{@code singleton.SingletonLazy@7852e922}. 通過反序列化,也可以得到新對(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() { // 防止反射漏洞通過再次調(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; } }
感謝各位的閱讀!關(guān)于“單例模式中反射漏洞和反序列化漏洞的示例分析”這篇文章就分享到這里了,希望以上內(nèi)容可以對(duì)大家有一定的幫助,讓大家可以學(xué)到更多知識(shí),如果覺得文章不錯(cuò),可以把它分享出去讓更多的人看到吧!