面向对象编程世界里的单例模式(Singleton)可能是设计模式里最简单的一种,大多数开发人员都觉得可以很容易掌握它的用法。单例模式保证一个类仅有一个实例,并提供一个访问它的全局访问点。

然而在某些场景下,这种设计模式的单例特性会被破坏,看下面这个例子:

代码的第三行,这个ABAP类实现了接口if_serializable_object,这意味着它可以被关键字CALL TRANSFORMATION进行序列化和反序列化操作。

使用下面的ABAP代码:

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.

执行之后,在调试器里发现lo_instance和lo_instance2指向了两个不同的对象实例,说明此时这个ABAP单例模式已经被破坏了。

再看看Java,下面是一个最简单的Java单例模式:

然而我们仍然可以通过Java的反射机制来破坏这个单例:

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

在Java里,我们可以通过枚举类来防御这种反射攻击:

public enum JerrySingletonAnotherApproach {
INSTANCE ; private String name = "Jerry" ; public String getName() {
return this.name;
}
}

这种单例模式的消费代码:

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

此时别有用心的攻击者如果想使用反射机制创建新的实例,会收到下面的报错信息:

Exception in thread "main" java.lang.NoSuchMethodException: singleton.JerrySingletonAnotherApproach.()

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)

要获取更多Jerry的原创文章,请关注公众号"汪子熙":

ABAP和Java里的单例模式攻击的更多相关文章

  1. ABAP和Java里关于DEFAULT(默认)机制的一些语言特性

    ABAP 740的新语法: 上图的代码相当于: DATA: ls_data LIKE LINE OF it_data. READ TABLE it_data INTO ls_data WITH KEY ...

  2. ABAP和Java单例模式的攻防

    ABAP CLASS zcl_jerry_singleton DEFINITION PUBLIC FINAL CREATE PRIVATE . PUBLIC SECTION. INTERFACES i ...

  3. 使用Java+SAP云平台+SAP Cloud Connector调用ABAP On-Premise系统里的函数

    最近Jerry接到一个原型开发的任务,需要在微信里调用ABAP On Premise系统(SAP CRM On-Premise)里的某些函数.具体场景和我之前的公众号文章 Cloud for Cust ...

  4. java的设计模式 - 单例模式

    java 面试中单例模式基本都是必考的,都有最推荐的方式,也不知道问来干嘛.下面记录一下 饿汉式(也不知道为何叫这个名字) public class Singleton { private stati ...

  5. ABAP和Java的单元测试Unit Test

    ABAP ABAP class单元测试的执行入口,CLASS_SETUP, 是硬编码在单元测试框架实现CL_AUNIT_TEST_CLASS里的. 待执行的单元测试方法通过CL_AUNIT_TEST_ ...

  6. ABAP vs Java, 蛙泳 vs 自由泳

    去年7月定下的一年之内学会自由泳的目标终于实现了,特来还愿. ABAP和Java, 蛙泳和自由泳.前面的组合是Jerry用来挣钱养家的技术,后者是Jerry花了大量业余时间和金钱苦练的技能.或许有的朋 ...

  7. Java设计模式之单例模式 - Singleton

    用来创建独一无二的,是能有一个实例的对象的入场券.告诉你一个好消息,单例模式的类图可以说是所有模式的类图中最简单的,事实上,它的类图上只有一个类!但是,可不要兴奋过头,尽管从类设计的视角来说很简单,但 ...

  8. [java设计模式]之单例模式

    -------------------此部分比較深入地解说了单例模式,原文链接已给出.兴许将涉及一些常见面试问题--------------------------- 原文地址:http://www. ...

  9. SAP云平台上的ABAP编程环境里如何消费第三方服务

    在ABAP On-Premises环境下,使用ABAP编程消费第三方服务,相信很多ABAP顾问都已经非常熟悉了,无非就是使用CL_HTTP_CLIENT或者CL_REST_HTTP_CLIENT来发送 ...

随机推荐

  1. avformat_open_input阻塞操作中断的支持

    avformat_open_input默认是阻塞操作,如果不加控制,等待时间可能会达到30s以上,对于有些情况,等待30s的体验是无法接受的. ffmpeg支持interrupt_callback机制 ...

  2. 如何学会快速调用API

    作为一名苦逼的程序员,在实现各种需求的过程中,总是需要调用各种各样的API,也就是要读各种文档.我们所要做的是弄清楚这些API的参数然后调用即可.说起来非常简单,是实际上却不是这样.现在火爆的机器学习 ...

  3. Lamda OrderBy 排序问题

    var itemModel = itemList.OrderBy(s=> decimal.Parse(s.Price)).ToList(); 前端传递的list数据金额或者其他非数字类型的字段最 ...

  4. bootstrap-select

    bootstrap-select 周下载量 63,214 是bootstrap中select库下载量最多的. https://www.npmjs.com/package/bootstrap-selec ...

  5. 在条件判断中使用 all() / any()

    在条件判断中使用 all() / any() all() 和 any() 两个函数非常适合在条件判断中使用.这两个函数接受一个可迭代对象,返回一个布尔值,其中: all(seq):仅当 seq 中所有 ...

  6. Idea导入maven项目没有识别

    选中module的pom.xml,右键,选择" add as maven project",idea会识别该pom的项目  

  7. java Random 抢红包算法

    红包有一个总金额和总数量,领的时候随机分配金额. 维护一个剩余总金额和总数量,分配时,如果数量等于1,直接返回总金额,如果大于1,则计算平均值,并设定随机最大值为平均值的两倍,然后取一个随机值,如果随 ...

  8. Doker容器部署Tomcat服务器

    1.拉取tomcat服务镜像文件 root@ubuntu:~# docker pull registry.cn-hangzhou.aliyuncs.com/xxxx/xxxxx:web web: Pu ...

  9. linux服务器之间文件传输

    有时候我们会遇到,把一个服务器上的文件夹,传到另一个服务器 我们需要先把文件夹打包成 tar.gz,这种格式在任何linux版本上都能压缩/解压 #解压命令 tar -zxvf xxx.tar.gz ...

  10. STL之空间配置器allocator

    摘要 C++STL的空间配置器将内存的分配.释放,对象的构造.析构都分开执行,内存分配由alloc::allocate()负责,内存的释放由alloc::deallocate()负责:对象的构造由:: ...