程式設計師面試系列之Java單例模式的攻擊與防禦
我寫的程式設計師面試系列
Java面試系列-webapp資料夾和WebContent資料夾的區別?
程式設計師面試系列:Spring MVC能響應HTTP請求的原因?
Java程式設計師面試系列-什麼是Java Marker Interface(標記介面)
JavaScript面試系列:JavaScript設計模式之橋接模式和懶載入
使用JavaScript ES6的新特性計算Fibonacci(非波拉契數列)
單例模式在很多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列舉方式實現的單例,列舉類沒有傳統意義上的建構函式,因此對這種反射攻擊免疫。
要獲取更多Jerry的原創技術文章,請關注公眾號"汪子熙"或者掃描下面二維碼:
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/24475491/viewspace-2214340/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- WEB攻擊與防禦Web
- CSRF攻擊與防禦
- Java設計模式系列之單例設計模式Java設計模式單例
- 淺談DDOS攻擊攻擊與防禦
- WMI 的攻擊,防禦與取證分析技術之防禦篇
- 《JAVA與設計模式》之單例模式Java設計模式單例
- WMI 的攻擊,防禦與取證分析技術之攻擊篇
- 淺談DDos攻擊與防禦
- Java設計模式之單例模式Java設計模式單例
- CSS keylogger:攻擊與防禦CSS
- 生成樹欺騙攻擊與防禦策略
- 淺談 JavaScript DDoS 攻擊原理與防禦JavaScript
- 淺談JavaScript DDoS攻擊原理與防禦JavaScript
- 淺談JS DDoS攻擊原理與防禦JS
- 伺服器防禦流量攻擊的簡單方法!伺服器
- Kotlin 設計模式系列之單例模式Kotlin設計模式單例
- Java HTTP Host 頭攻擊原理以及如何防禦JavaHTTP
- 高防伺服器主要防禦的攻擊伺服器
- ARP病毒攻擊技術分析與防禦
- DDoS 攻擊與防禦:從原理到實踐
- 設計模式系列-單例模式設計模式單例
- CC攻擊的原理是什麼?如何防禦CC攻擊?
- 折騰Java設計模式之單例模式Java設計模式單例
- Java設計模式之單例模式(Singleton)Java設計模式單例
- cc攻擊防禦解決方法
- 網站被攻擊如何防禦網站
- 細說DDoS攻擊的趨勢與防禦策略(轉)
- 12行JS程式碼的DoS攻擊分析及防禦JS
- DDOS伺服器防禦的方法有哪些,如何防禦DDOS攻擊伺服器
- 解決DDoS攻擊的趨勢與防禦策略的方法
- XXE攻擊攻擊原理是什麼?如何防禦XXE攻擊?
- 抵禦惡意http攻擊,使用redis製作一個簡單的防禦HTTPRedis
- Java設計模式之單例模式(Singleton Pattern)Java設計模式單例
- JAVA設計模式之 單例模式【Singleton Pattern】Java設計模式單例
- 設計模式之單例設計模式設計模式單例
- Java設計模式–單例模式Java設計模式單例
- Java設計模式——單例模式Java設計模式單例
- Java設計模式--單例模式Java設計模式單例