摘要:然而我只需要将这个单例类的构造函数通过反射设置成可以访问,然后就能通过反射调用该构造函数,进而生成新的对象实例。针对这种攻击,一种可行的防御措施是在单例类的构造函数内定义一个布尔变量,初始化为。当构造函数执行后,该变量被置为。
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. *---------------------------------------------------------------------------------------+ * | Static Public Method ZCL_JERRY_SINGLETON=>CLASS_CONSTRUCTOR * +-------------------------------------------------------------------------------------------------+ * +-------------------------------------------------------------------------------------- METHOD class_constructor. so_instance = NEW zcl_jerry_singleton( ). ENDMETHOD. *---------------------------------------------------------------------------------------+ * | Instance Public Method ZCL_JERRY_SINGLETON->CONSTRUCTOR * +-------------------------------------------------------------------------------------------------+ * +-------------------------------------------------------------------------------------- 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. *---------------------------------------------------------------------------------------+ * | Static Public Method ZCL_JERRY_SINGLETON=>GET_INSTANCE * +-------------------------------------------------------------------------------------------------+ * | [<-()] RO_INSTANCE TYPE REF TO ZCL_JERRY_SINGLETON * +-------------------------------------------------------------------------------------- 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的原创文章,请关注公众号"汪子熙":
文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。
转载请注明本文地址:https://www.ucloud.cn/yun/71933.html
摘要:本文会以引出问题为主,后面有时间的话,笔者陆续会抽些重要的知识点进行详细的剖析与解答。敬请关注服务端思维微信公众号,获取最新文章。 原文地址:梁桂钊的博客博客地址:http://blog.720ui.com 这里,笔者结合自己过往的面试经验,整理了一些核心的知识清单,帮助读者更好地回顾与复习 Java 服务端核心技术。本文会以引出问题为主,后面有时间的话,笔者陆续会抽些重要的知识点进...
摘要:这是年的第篇文章,也是汪子熙公众号总共第篇原创文章。使用通过格式发送和文件到服务器关于格式的详细说明,参考开发社区和的文档我在前文例子的基础上稍作修改在里使用两个类型为的标签,分别上传和文件用来测试的本地文件,大小为字节。 这是 Jerry 2021 年的第 71 篇文章,也是汪子熙公众号总共第 348 篇原创文章。 Jerry 之前发布过一篇文章 不使用任何框架,手写纯 Jav...
摘要:目前被广泛用于和的众多应用中,以及和一些正在开发的新一代云产品中。年月时,我和德国一位负责的同事就这个话题在半小时的电话会议里产生了争执。德国同事看了之后,同意了我的意见。和微信集成系列教程这个系列教程里,和微信的交互,使用了,使用了。 OData(Open Data Protocol)协议是一个开放的工业标准,用于定义RESTFul API的设计和使用。我的文章标题前加上SAP的前缀...
摘要:目前被广泛用于和的众多应用中,以及和一些正在开发的新一代云产品中。年月时,我和德国一位负责的同事就这个话题在半小时的电话会议里产生了争执。德国同事看了之后,同意了我的意见。和微信集成系列教程这个系列教程里,和微信的交互,使用了,使用了。 OData(Open Data Protocol)协议是一个开放的工业标准,用于定义RESTFul API的设计和使用。我的文章标题前加上SAP的前缀...
阅读 1716·2021-10-11 10:59
阅读 2385·2021-09-30 09:53
阅读 1731·2021-09-22 15:28
阅读 2776·2019-08-29 15:29
阅读 1534·2019-08-29 13:53
阅读 3171·2019-08-29 12:34
阅读 2833·2019-08-26 10:16
阅读 2600·2019-08-23 15:16