单例模式反射机制漏洞

一、反射漏洞

单例模式五种实现方法中,除了枚举式,存在反射和反序列化漏洞,即通过反射和反序列化可以破解以上几种实现方式。在这里,我们仅举例反射漏洞以及如何避免反射漏洞。

比如,懒汉式单例模式,我们可以通过反射调用私有构造器。

package com.DesignPattern;

//懒汉式单例模式
public class Singleton {
	private static Singleton instance = null;
	
	private Singleton(){
		/*
		//可以在构造方法中手动抛出异常,解决反射漏洞问题
		if(instance!=null){
			throw new RuntimeException();
		}
		*/
		
	}
	
	public static synchronized Singleton getInstance(){
		
		if(instance==null){
			instance = new Singleton();
		}
		return instance;
	}

}

package com.DesignPattern;

import java.lang.reflect.Constructor;

public class Client {

	public static void main(String[] args) {
		Singleton instance = Singleton.getInstance();
		Singleton instance2 = Singleton.getInstance();
		System.out.println(instance);
		System.out.println(instance2);
		
		//通过反射方法调用私有构造器
		Class clazz;
		try {
			clazz = (Class) Class.forName("com.DesignPattern.Singleton");
			Constructor constructor = clazz.getDeclaredConstructor(null);
			constructor.setAccessible(true);
			Singleton instance3 = constructor.newInstance();
			Singleton instance4 = constructor.newInstance();
			System.out.println(instance3);
			System.out.println(instance4);
		} catch (Exception e) {
			e.printStackTrace();
		}		
		
	}
}

运行结果

二、解决方法

可以在构造方法中手动抛出异常,解决反射漏洞问题。修改后的单例模式如下

package com.DesignPattern;

//懒汉式单例模式
public class Singleton {
	private static Singleton instance = null;
	
	private Singleton(){
		
		//可以在构造方法中手动抛出异常,解决反射漏洞问题
		if(instance!=null){
			throw new RuntimeException();
		}	
	}
	
	public static synchronized Singleton getInstance(){
		
		if(instance==null){
			instance = new Singleton();
		}
		return instance;
	}

}

这样,因为内存中以存在该单例模式对象,所以通过反射调用私有构造器时,抛出异常

单例模式反射机制漏洞_第1张图片


你可能感兴趣的:(Java)