溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

Java單例模式的攻擊與防御怎么理解

發(fā)布時間:2022-01-04 15:35:00 來源:億速云 閱讀:133 作者:iii 欄目:編程語言

這篇文章主要介紹“Java單例模式的攻擊與防御怎么理解”,在日常操作中,相信很多人在Java單例模式的攻擊與防御怎么理解問題上存在疑惑,小編查閱了各式資料,整理出簡單好用的操作方法,希望對大家解答”Java單例模式的攻擊與防御怎么理解”的疑惑有所幫助!接下來,請跟著小編一起來學習吧!

說到“單例模式被攻擊”這個話題,大家最容易想到的可能就是通過序列化/反序列化來攻擊單例模式,因為一個對象實例序列化再反序列化后,得到的新的對象雖然各字段內容和原字段一致,然而對象地址和原始對象地址相比已經發(fā)生了變化,因此它們是兩個不同的對象。

上面的結論完全正確,然而除了序列化/反序列化,單例模式還可能遭受另一種方式的攻擊,即反射攻擊(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;
      }
}

Java單例模式的攻擊與防御怎么理解

上面是一個餓漢式單例。

Java單例模式的攻擊與防御怎么理解

然而我只需要將這個單例類JerrySingleton的構造函數(shù)通過反射設置成可以訪問Accessible,然后就能通過反射調用該構造函數(shù),進而生成新的對象實例。這樣就破壞了單例模式。

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);

Java單例模式的攻擊與防御怎么理解

第6行代碼會打印false。

針對這種攻擊,一種可行的防御措施是在單例類的構造函數(shù)內定義一個布爾變量,初始化為false。當構造函數(shù)執(zhí)行后,該變量被置為true。如果接下來構造函數(shù)再次被執(zhí)行,則人為拋出異常,避免構造函數(shù)重復執(zhí)行。

public class JerrySingletonImproved {    private static boolean flag = false;    private JerrySingletonImproved(){         synchronized(JerrySingletonImproved.class) {            if(flag == false) {
                  flag = !flag;
            }      else {              throw new RuntimeException("Singleton violated");
      }
  }
}
}

Java單例模式的攻擊與防御怎么理解

這種防御措施無法從根本上杜絕Singleton被攻擊,因為攻擊者仍舊可以通過反射來修改布爾變量flag的值,從而繞過這個檢查。

最理想的不會受到攻擊的單例模式實現(xiàn)是借助Java里枚舉類Enumeration的特性:

Java單例模式的攻擊與防御怎么理解

這種實現(xiàn)類型的單例模式的消費代碼:

System.out.println("Name:" + JerrySingletonAnotherApproach.INSTANCE.getName());

如果攻擊者通過前面介紹的反射代碼對這種實現(xiàn)方式的單例進行攻擊,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單例模式的攻擊與防御怎么理解

究其原因,是因為現(xiàn)在我們是通過Java枚舉方式實現(xiàn)的單例,枚舉類沒有傳統(tǒng)意義上的構造函數(shù),因此對這種反射攻擊免疫。

到此,關于“Java單例模式的攻擊與防御怎么理解”的學習就結束了,希望能夠解決大家的疑惑。理論與實踐的搭配能更好的幫助大家學習,快去試試吧!若想繼續(xù)學習更多相關知識,請繼續(xù)關注億速云網(wǎng)站,小編會繼續(xù)努力為大家?guī)砀鄬嵱玫奈恼拢?/p>

向AI問一下細節(jié)

免責聲明:本站發(fā)布的內容(圖片、視頻和文字)以原創(chuàng)、轉載和分享為主,文章觀點不代表本網(wǎng)站立場,如果涉及侵權請聯(lián)系站長郵箱:is@yisu.com進行舉報,并提供相關證據(jù),一經查實,將立刻刪除涉嫌侵權內容。

AI