免费视频淫片aa毛片_日韩高清在线亚洲专区vr_日韩大片免费观看视频播放_亚洲欧美国产精品完整版

打開APP
userphoto
未登錄

開通VIP,暢享免費(fèi)電子書等14項(xiàng)超值服

開通VIP
程序員面試系列之Java單例模式的攻擊與防御

單例模式在很多Java程序員的眼中,應(yīng)該是設(shè)計(jì)模式里最簡(jiǎn)單的一種了。那么單例模式可能會(huì)被攻擊,您聽說(shuō)過(guò)么?

說(shuō)到“單例模式被攻擊”這個(gè)話題,大家最容易想到的可能就是通過(guò)序列化/反序列化來(lái)攻擊單例模式,因?yàn)橐粋€(gè)對(duì)象實(shí)例序列化再反序列化后,得到的新的對(duì)象雖然各字段內(nèi)容和原字段一致,然而對(duì)象地址和原始對(duì)象地址相比已經(jīng)發(fā)生了變化,因此它們是兩個(gè)不同的對(duì)象。

上面的結(jié)論完全正確,然而除了序列化/反序列化,單例模式還可能遭受另一種方式的攻擊,即反射攻擊(Reflection attack)。

看一個(gè)具體例子:

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

上面是一個(gè)餓漢式單例。

然而我只需要將這個(gè)單例類JerrySingleton的構(gòu)造函數(shù)通過(guò)反射設(shè)置成可以訪問(wèn)Accessible,然后就能通過(guò)反射調(diào)用該構(gòu)造函數(shù),進(jìn)而生成新的對(duì)象實(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);

第6行代碼會(huì)打印false。

針對(duì)這種攻擊,一種可行的防御措施是在單例類的構(gòu)造函數(shù)內(nèi)定義一個(gè)布爾變量,初始化為false。當(dāng)構(gòu)造函數(shù)執(zhí)行后,該變量被置為true。如果接下來(lái)構(gòu)造函數(shù)再次被執(zhí)行,則人為拋出異常,避免構(gòu)造函數(shù)重復(fù)執(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");      }  }}}

這種防御措施無(wú)法從根本上杜絕Singleton被攻擊,因?yàn)楣粽呷耘f可以通過(guò)反射來(lái)修改布爾變量flag的值,從而繞過(guò)這個(gè)檢查。

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

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

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

如果攻擊者通過(guò)前面介紹的反射代碼對(duì)這種實(shí)現(xiàn)方式的單例進(jìn)行攻擊,JDK會(huì)拋出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)

究其原因,是因?yàn)楝F(xiàn)在我們是通過(guò)Java枚舉方式實(shí)現(xiàn)的單例,枚舉類沒(méi)有傳統(tǒng)意義上的構(gòu)造函數(shù),因此對(duì)這種反射攻擊免疫。

要獲取更多Jerry的原創(chuàng)技術(shù)文章,請(qǐng)關(guān)注公眾號(hào)"汪子熙"

搜索

復(fù)制

本站僅提供存儲(chǔ)服務(wù),所有內(nèi)容均由用戶發(fā)布,如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請(qǐng)點(diǎn)擊舉報(bào)。
打開APP,閱讀全文并永久保存 查看更多類似文章
猜你喜歡
類似文章
ABAP面向?qū)ο笾畣卫J剑⊿ingleton Pattern)
C# 設(shè)計(jì)模式-單例模式
設(shè)計(jì)模式之單例模式
設(shè)計(jì)模式-----單例模式(Singleton Pattern)
java簡(jiǎn)單單例設(shè)計(jì)模式-餓漢式||無(wú)線程鎖懶漢
C與設(shè)計(jì)模式講義筆記(干貨)
更多類似文章 >>
生活服務(wù)
分享 收藏 導(dǎo)長(zhǎng)圖 關(guān)注 下載文章
綁定賬號(hào)成功
后續(xù)可登錄賬號(hào)暢享VIP特權(quán)!
如果VIP功能使用有故障,
可點(diǎn)擊這里聯(lián)系客服!

聯(lián)系客服