ABAP和Java單例模式的攻防
ABAP
CLASS zcl_jerry_singleton DEFINITION PUBLIC FINAL CREATE PRIVATE . PUBLIC SECTION. INTERFACES if_serializable_object . CLASS-METHODS class_constructor . CLASS-METHODS get_instance RETURNING VALUE(ro_instance) TYPE REF TO zcl_jerry_singleton . PROTECTED SECTION. PRIVATE SECTION. CLASS-DATA so_instance TYPE REF TO zcl_jerry_singleton . DATA mv_name TYPE string . DATA mv_initialized TYPE abap_bool . METHODS constructor . ENDCLASS. CLASS ZCL_JERRY_SINGLETON IMPLEMENTATION. * <SIGNATURE>---------------------------------------------------------------------------------------+ * | Static Public Method ZCL_JERRY_SINGLETON=>CLASS_CONSTRUCTOR * +-------------------------------------------------------------------------------------------------+ * +--------------------------------------------------------------------------------------</SIGNATURE> METHOD class_constructor. so_instance = NEW zcl_jerry_singleton( ). ENDMETHOD. * <SIGNATURE>---------------------------------------------------------------------------------------+ * | Instance Public Method ZCL_JERRY_SINGLETON->CONSTRUCTOR * +-------------------------------------------------------------------------------------------------+ * +--------------------------------------------------------------------------------------</SIGNATURE> METHOD constructor. mv_name = 'Jerry'. IF mv_initialized = abap_false. mv_initialized = abap_true. ELSE. MESSAGE 'you are in trouble!' TYPE 'E' DISPLAY LIKE 'I'. ENDIF. ENDMETHOD. * <SIGNATURE>---------------------------------------------------------------------------------------+ * | Static Public Method ZCL_JERRY_SINGLETON=>GET_INSTANCE * +-------------------------------------------------------------------------------------------------+ * | [<-()] RO_INSTANCE TYPE REF TO ZCL_JERRY_SINGLETON * +--------------------------------------------------------------------------------------</SIGNATURE> METHOD get_instance. ro_instance = so_instance. ENDMETHOD. ENDCLASS.
透過序列化/反序列化攻擊單例模式:
DATA(lo_instance) = zcl_jerry_singleton=>get_instance( ). DATA: s TYPE string.CALL TRANSFORMATION id SOURCE model = lo_instance RESULT XML s. DATA: lo_instance2 TYPE REF TO zcl_jerry_singleton.CALL TRANSFORMATION id SOURCE XML s RESULT model = lo_instance2.
繞過了單例的限制,構造了第二個例項。
Java
除了用序列化/反序列化攻擊外,還可以用反射攻擊。
然而我只需要將這個單例類JerrySingleton的建構函式透過反射設定成可以訪問Accessible,然後就能透過反射呼叫該建構函式,進而生成新的物件例項。這樣就破壞了單例模式。
第6行程式碼會列印false。
針對這種攻擊,一種可行的防禦措施是在單例類的建構函式內定義一個布林變數,初始化為false。當建構函式執行後,該變數被置為true。如果接下來建構函式再次被執行,則人為丟擲異常,避免建構函式重複執行。
這種防禦措施無法從根本上杜絕Singleton被攻擊,因為攻擊者仍舊可以透過反射來修改布林變數flag的值,從而繞過這個檢查。
最理想的不會受到攻擊的單例模式實現是藉助Java裡列舉類Enumeration的特性:
這種實現型別的單例模式的消費程式碼:
System.out.println("Name:" + JerrySingletonAnotherApproach.INSTANCE.getName());
如果攻擊者透過前面介紹的反射程式碼對這種實現方式的單例進行攻擊,JDK會丟擲NoSuchMethodException異常:
究其原因,是因為現在我們是透過Java列舉方式實現的單例,列舉類沒有傳統意義上的建構函式,因此對這種反射攻擊免疫。
要獲取更多Jerry的原創文章,請關注公眾號"汪子熙":
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/24475491/viewspace-2216831/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- 設計模式:單例模式的使用和實現(JAVA)設計模式單例Java
- java 單例模式Java單例模式
- Java單例模式Java單例模式
- java單例模式懶漢和餓漢Java單例模式
- Java單例模式:缺點和優點Java單例模式
- 我的Java設計模式-單例模式Java設計模式單例
- Java設計模式–單例模式Java設計模式單例
- Java設計模式——單例模式Java設計模式單例
- Java設計模式--單例模式Java設計模式單例
- Java設計模式 | 單例模式Java設計模式單例
- Java設計模式【單例模式】Java設計模式單例
- Java設計模式-單例模式Java設計模式單例
- java中的單例模式,舉例說明。Java單例模式
- java單例設計模式Java單例設計模式
- 淺析單例模式--Java單例模式Java
- Java基礎-單例模式Java單例模式
- Java單例模式詳解Java單例模式
- java單例模式深度解析Java單例模式
- 【Java面試指北】單例模式Java面試單例模式
- Java設計模式之單例模式Java設計模式單例
- Java設計模式4:單例模式Java設計模式單例
- Java常用設計模式-單例模式Java設計模式單例
- Java中的單例模式最全解析Java單例模式
- ABAP和Java的單元測試Unit TestJava
- Java基礎-static關鍵字和單例模式Java單例模式
- Java設計模式——單例模式(建立型模式)Java設計模式單例
- java設計模式其一 單例模式Java設計模式單例
- java設計模式-單例模式SingletonJava設計模式單例
- 《JAVA與設計模式》之單例模式Java設計模式單例
- 設計模式-Java實現單例模式設計模式Java單例
- 單例模式的 Java 實現與思考單例模式Java
- Java:單例模式的七種寫法Java單例模式
- ABAP和Java SpringBoot的單元測試JavaSpring Boot
- java 、HashMap 和單例JavaHashMap單例
- 折騰Java設計模式之單例模式Java設計模式單例
- Java設計模式——單例模式(Singleton pattern)Java設計模式單例
- Java 中設計模式 (單例模式) 介紹Java設計模式單例
- Java設計模式之單例模式(Singleton)Java設計模式單例