单例模式-反射攻击的解决方案及原理分析

Posted shenwen

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了单例模式-反射攻击的解决方案及原理分析相关的知识,希望对你有一定的参考价值。

首先我们还是拿饿汉模式作为栗子进行测试,饿汉模式的代码如下:

public class HungrySingleton implements Serializable {

    private static final HungrySingleton instance;

    static {
        instance = new HungrySingleton();
    }
    private HungrySingleton(){
    }

    public static HungrySingleton getInstance(){
        return instance;
    }

    private Object readResolve(){
        return instance;
    }

  1、先写一个利用反射获取实例的方法和直接获取实例的方法,将两者的返回值进行比较,看返回的是否是一个实例。

代码如下:

public class Testreflection {
    public static void main(String[] args) throws NoSuchMethodException, IllegalAccessException, InvocationTargetException, InstantiationException {
        Class object = HungrySingleton.class;
        Constructor constructor = object.getDeclaredConstructor();
        constructor.setAccessible(true);

        HungrySingleton instance = HungrySingleton.getInstance();
        HungrySingleton newInstance = (HungrySingleton) constructor.newInstance();

        System.out.println(instance);
        System.out.println(newInstance);
        System.out.println(instance == newInstance);

     }
    }

  运行后的结果为:可见,两者的结果并不是一个对象,则饿汉模式毅然受到了反射的攻击。

技术图片

 

2、那么改如何解决这反射攻击呢?我们知道是在类加载的时候就加载了这个实例的,因为是在类加载的时候就生成了词实例,那么我们可以在构造器里面加一个判断,进行反射防御。代码如下:

技术图片

 

测试结果为:

技术图片

这种方式有一个特点,也就是它对类加载这个时刻就把对象创建好的这种类是ok的,静态内部类的单例也可以用。
对于不是静态类的也需要解决下,要根据创建实例的顺序进行解决。但是无论如何反射都可以访问到类的方法和变量,进行修改,所以非
类加载这个时刻就把对象创建好的这种类,是不能防止反射攻击的。

 

以上是关于单例模式-反射攻击的解决方案及原理分析的主要内容,如果未能解决你的问题,请参考以下文章

单例模式详解

三单例模式详解

单例模式反射序列化漏洞及解决方案!

从源码中学习设计模式系列——单例模式序/反序列化以及反射攻击的问题

如何防止单例模式被JAVA反射攻击

单例模式如何防止反射攻击