• 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的原创文章,请关注公众号"汪子熙":

  • 相关阅读:
    SpringMVC 学习笔记(四) 处理模型数据
    UE4关于Oculus Rift (VR)开发忠告
    电子商务系统的设计与实现(十三):分页组件,从前到后,从JS到Java
    2014年工作中遇到的10个问题:221-230
    2014年工作中遇到的10个问题:221-230
    公司新年第一次全员大会小记
    公司新年第一次全员大会小记
    雷观(十八):我的世界观
    雷观(十八):我的世界观
    今天烦死了,各种技术,各种问题,全栈式多屏工程师不好做啊
  • 原文地址:https://www.cnblogs.com/sap-jerry/p/9821661.html
Copyright © 2020-2023  润新知