设计模式-单例模式防止反射漏洞攻击

// *****************************现象描述*******************************
package com.example.SpringBootTest1.shejimoshi.singleton;
public class InnerclassSingleton {
private InnerclassSingleton() {};
private static class Singleton {
private static final InnerclassSingleton i = new InnerclassSingleton();
}

public static InnerclassSingleton getInstance() {
return Singleton.i;
}
}

// 通过反射获取对象拿到的对象不是同一个
public class Test {
public static void main(String[] args) throws NoSuchMethodException, InvocationTargetException, InstantiationException, IllegalAccessException {
Constructor<InnerclassSingleton> declaredConstructor = InnerclassSingleton.class.getDeclaredConstructor();
declaredConstructor.setAccessible(true);
InnerclassSingleton instance1 = declaredConstructor.newInstance();
InnerclassSingleton instance2 = InnerclassSingleton.getInstance();
System.out.println(instance1 == instance2); // false
}
}

// *********************************防止漏洞攻击*****************************
package com.example.SpringBootTest1.shejimoshi.singleton;
public class InnerclassSingleton {
private InnerclassSingleton() {
if (InnerclassSingleton.getInstance() != null) {
throw new RuntimeException("单例模式不允许创建多个实例");
}
};

private static class Singleton {
private static final InnerclassSingleton i = new InnerclassSingleton();
}

public static InnerclassSingleton getInstance() {
return Singleton.i;
}
}

// 运行这段代码通过反射去创建实例时会报自定义异常, 从而达到防止反射漏洞攻击
public class Test {
public static void main(String[] args) throws NoSuchMethodException, InvocationTargetException, InstantiationException, IllegalAccessException {
Constructor<InnerclassSingleton> declaredConstructor = InnerclassSingleton.class.getDeclaredConstructor();
declaredConstructor.setAccessible(true);
InnerclassSingleton instance1 = declaredConstructor.newInstance();
InnerclassSingleton instance2 = InnerclassSingleton.getInstance();
System.out.println(instance1 == instance2);
}
}

 

posted @ 2022-02-25 13:33  剑阁丶神灯  阅读(67)  评论(0编辑  收藏  举报