您好,登錄后才能下訂單哦!
這篇文章主要介紹“Java單例模式的攻擊與防御怎么理解”,在日常操作中,相信很多人在Java單例模式的攻擊與防御怎么理解問題上存在疑惑,小編查閱了各式資料,整理出簡單好用的操作方法,希望對大家解答”Java單例模式的攻擊與防御怎么理解”的疑惑有所幫助!接下來,請跟著小編一起來學習吧!
說到“單例模式被攻擊”這個話題,大家最容易想到的可能就是通過序列化/反序列化來攻擊單例模式,因為一個對象實例序列化再反序列化后,得到的新的對象雖然各字段內容和原字段一致,然而對象地址和原始對象地址相比已經發生了變化,因此它們是兩個不同的對象。
上面的結論完全正確,然而除了序列化/反序列化,單例模式還可能遭受另一種方式的攻擊,即反射攻擊(Reflection attack)。
看一個具體例子:
public class JerrySingleton { private String name; private JerrySingleton(){ name = "Jerry"; }private static class SingletonHolder{ private static final JerrySingleton INSTANCE = new JerrySingleton(); }public static JerrySingleton getInstance() { return SingletonHolder.INSTANCE; } }
上面是一個餓漢式單例。
然而我只需要將這個單例類JerrySingleton的構造函數通過反射設置成可以訪問Accessible,然后就能通過反射調用該構造函數,進而生成新的對象實例。這樣就破壞了單例模式。
Class<?> classType = JerrySingleton.class; Constructor<?> c = classType.getDeclaredConstructor(null); c.setAccessible(true); JerrySingleton e1 = (JerrySingleton)c.newInstance(); JerrySingleton e2 = JerrySingleton.getInstance(); System.out.println(e1 == e2);
第6行代碼會打印false。
針對這種攻擊,一種可行的防御措施是在單例類的構造函數內定義一個布爾變量,初始化為false。當構造函數執行后,該變量被置為true。如果接下來構造函數再次被執行,則人為拋出異常,避免構造函數重復執行。
public class JerrySingletonImproved { private static boolean flag = false; private JerrySingletonImproved(){ synchronized(JerrySingletonImproved.class) { if(flag == false) { flag = !flag; } else { throw new RuntimeException("Singleton violated"); } } } }
這種防御措施無法從根本上杜絕Singleton被攻擊,因為攻擊者仍舊可以通過反射來修改布爾變量flag的值,從而繞過這個檢查。
最理想的不會受到攻擊的單例模式實現是借助Java里枚舉類Enumeration的特性:
這種實現類型的單例模式的消費代碼:
System.out.println("Name:" + JerrySingletonAnotherApproach.INSTANCE.getName());
如果攻擊者通過前面介紹的反射代碼對這種實現方式的單例進行攻擊,JDK會拋出NoSuchMethodException異常:
Exception in thread "main" java.lang.NoSuchMethodException: singleton.JerrySingletonAnotherApproach.<init>() at java.lang.Class.getConstructor0(Class.java:3082) at java.lang.Class.getDeclaredConstructor(Class.java:2178) at singleton.SingletonAttack.test3(SingletonAttack.java:31) at singleton.SingletonAttack.main(SingletonAttack.java:43)
究其原因,是因為現在我們是通過Java枚舉方式實現的單例,枚舉類沒有傳統意義上的構造函數,因此對這種反射攻擊免疫。
到此,關于“Java單例模式的攻擊與防御怎么理解”的學習就結束了,希望能夠解決大家的疑惑。理論與實踐的搭配能更好的幫助大家學習,快去試試吧!若想繼續學習更多相關知識,請繼續關注億速云網站,小編會繼續努力為大家帶來更多實用的文章!
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。