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

ABAP和Java单例模式的攻防的更多相关文章
- ABAP和Java里的单例模式攻击
面向对象编程世界里的单例模式(Singleton)可能是设计模式里最简单的一种,大多数开发人员都觉得可以很容易掌握它的用法.单例模式保证一个类仅有一个实例,并提供一个访问它的全局访问点. 然而在某些场 ...
- 用java单例模式实现面板切换
1.首先介绍一下什么是单例模式: java单例模式是一种常见的设计模式,那么我们先看看懒汉模式: public class Singleton_ { //设为私有方法,防止被外部类引用或实例 priv ...
- 【深入】java 单例模式(转)
[深入]java 单例模式 关于单例模式的文章,其实网上早就已经泛滥了.但一个小小的单例,里面却是有着许多的变化.网上的文章大多也是提到了其中的一个或几个点,很少有比较全面且脉络清晰的文章,于是,我便 ...
- 深入Java单例模式(转)
深入Java单例模式 源自 http://devbean.blog.51cto.com/448512/203501 在GoF的23种设计模式中,单例模式是比较简单的一种.然而,有时候越是简单的东西越容 ...
- Java 单例模式的七种写法
Java 单例模式的七种写法 第一种(懒汉,线程不安全) public class Singleton { private static Singleton instance; private Sin ...
- java单例模式之懒汉式分析
转自:http://blog.csdn.net/withiter/article/details/8140338 今天中午闲着没事,就随便写点关于Java单例模式的.其实单例模式实现有很多方法,这里我 ...
- Java 单例模式探讨
以下是我再次研究单例(Java 单例模式缺点)时在网上收集的资料,相信你们看完就对单例完全掌握了 Java单例模式应该是看起来以及用起来简单的一种设计模式,但是就实现方式以及原理来说,也并不浅显哦. ...
- ABAP和Java里关于DEFAULT(默认)机制的一些语言特性
ABAP 740的新语法: 上图的代码相当于: DATA: ls_data LIKE LINE OF it_data. READ TABLE it_data INTO ls_data WITH KEY ...
- ABAP vs Java, 蛙泳 vs 自由泳
去年7月定下的一年之内学会自由泳的目标终于实现了,特来还愿. ABAP和Java, 蛙泳和自由泳.前面的组合是Jerry用来挣钱养家的技术,后者是Jerry花了大量业余时间和金钱苦练的技能.或许有的朋 ...
随机推荐
- pow()函数的精度问题
妈蛋这个坑了我大半个小时都想不出个原因..后来看到pow的定义才想起,数据类型很重要啊.. 1.底数用常量,指数用整型 #include <stdio.h> #include <ma ...
- 使用Axis2方式发布webService的三种方式
1.Axis2的下载和安装 首先可以下载如下两个zip包:axis2-1.6.1-bin.zipaxis2-1.6.1-war.zip其中 axis2-1.6.1-bin.zip文件中包含了Axis2 ...
- Python中生成随机数
目录 1. random模块 1.1 设置随机种子 1.2 random模块中的方法 1.3 使用:生成整形随机数 1.3 使用:生成序列随机数 1.4 使用:生成随机实值分布 2. numpy.ra ...
- How to use unity CreateExternalTexture on Android?
http://stackoverflow.com/questions/33324753/how-to-use-unity-createexternaltexture-on-android Can so ...
- day4列表作业详解
1.day4题目 day4作业 1,写代码,有如下列表,按照要求实现每一个功能 li = ["alex", "WuSir", "ritian" ...
- 如何使用JMeter从文件中提取数据
在性能测试方面,重用响应数据至关重要.几乎(如果不是全部!)负载测试场景假设您: 从先前的响应中提取有趣的方面,并在下一个请求中重用它们(也称为相关) 确保实际响应符合预期(又称断言) 因此,如果您是 ...
- css3椭圆运动
通过使用css3实现让元素椭圆运动.而不是圆形运动. 效果1:http://sandbox.runjs.cn/show/ignefell 效果2:http://runjs.cn/code/w2wxjy ...
- Struts2拦截器再认识
拦截器(Interceptor)是 Struts 2 的核心组成部分. Struts2 很多功能都是构建在拦截器基础之上的,例如文件的上传和下载.国际化.数据类型转换和数据校验等等. Struts2 ...
- python进阶01 面向对象、类、实例、属性封装、实例方法
python进阶01 面向对象.类.实例.属性封装.实例方法 一.面向对象 1.什么是对象 #一切皆对象,可以简单地将“对象”理解为“某个东西” #“对象”之所以称之为对象,是因为它具有属于它自己的“ ...
- hibernate Restrictions用法 HibernateTemplate Hibernate结合spring
常用方法 http://www.jb51.net/article/41541.htm ........................................... 博客分类: Hiberna ...