ABAP和Java单例模式的攻防

简介: 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枚举方式实现的单例,枚举类没有传统意义上的构造函数,因此对这种反射攻击免疫。


相关文章
|
9天前
|
设计模式 缓存 安全
Java设计模式的单例模式应用场景
Java设计模式的单例模式应用场景
21 4
|
6天前
|
SQL 安全 Java
Java Web应用的安全防护与攻防深度剖析
Java Web应用的安全防护与攻防深度剖析
|
13天前
|
设计模式 缓存 安全
Java设计模式的单例模式应用场景
Java设计模式的单例模式应用场景
20 8
|
10天前
|
设计模式 SQL 安全
Java设计模式:单例模式之六种实现方式详解(二)
Java设计模式:单例模式之六种实现方式详解(二)
|
12天前
|
Java
JAVA单例模式-双重检验锁(防止反射、序列化多个)
JAVA单例模式-双重检验锁(防止反射、序列化多个)
16 1
|
14天前
|
设计模式 缓存 安全
java中的设计模式&单例模式
java中的设计模式&单例模式
11 1
|
5天前
|
SQL 监控 安全
Java Web应用的安全防护与攻防策略
Java Web应用的安全防护与攻防策略
|
9天前
|
设计模式 安全 Java
在Java中实现单例模式的正确方法
在Java中实现单例模式的正确方法
|
10天前
|
设计模式 缓存 安全
【Java设计模式 - 创建型模式1】单例模式
【Java设计模式 - 创建型模式1】单例模式
5 0
|
12天前
|
设计模式 安全 Java
如何在Java中实现线程安全的单例模式
如何在Java中实现线程安全的单例模式