美文网首页
【设计模式】——单例模式_防止反射和反序列化的漏洞

【设计模式】——单例模式_防止反射和反序列化的漏洞

作者: 从不打小怪兽 | 来源:发表于2020-06-15 15:53 被阅读0次

无题

  1. 通过反射
/**
 * 如何防止反射漏洞
 * @author admin
 *
 */

public class CrackSingleton {
    
    public static void main(String[] args) throws Exception{
        
        SingletonPattern06 s=SingletonPattern06.getInstance();
        System.out.println(s);
        
        //通过反射的方法直接调用私有的构造器————>空构造器添加判断
        Class<SingletonPattern06> clz=(Class<SingletonPattern06>)Class.forName("com.fgy.singleton.SingletonPattern06");
        Constructor<SingletonPattern06> c=clz.getDeclaredConstructor(null);
        c.setAccessible(true);
        SingletonPattern06 s1=c.newInstance();
        SingletonPattern06 s2=c.newInstance();
        
        System.out.println(s1);
        System.out.println(s2);

控制台:

com.fgy.singleton.SingletonPattern06@6bbc4459
com.fgy.singleton.SingletonPattern06@5d888759
com.fgy.singleton.SingletonPattern06@2e6e1408

解决方法:\color{red}{↓}构造器私有化的时候添加判断句\color{red}{↓}

    private SingletonPattern06(){
        if(st2!=null){
            throw new RuntimeException("防止反射漏洞");
        }
    }

再重新运行,就ok了

  1. 通过反序列化漏洞
/**
 * 如何防止反射和反序列化漏洞
 * @author admin
 *
 */

public class CrackSingleton {
    
    public static void main(String[] args) throws Exception{
        
        SingletonPattern06 s=SingletonPattern06.getInstance();
        System.out.println(s);
        
        //通过反序列化生成多个对象————>解决方法使用readresolve方法
        ObjectOutputStream oos=new ObjectOutputStream(new FileOutputStream("src/反序列化生成多个对象.txt"));
        oos.writeObject(s);
        oos.close();
        
        ObjectInputStream ois=new ObjectInputStream(new FileInputStream("src/反序列化生成多个对象.txt"));
        SingletonPattern06 s3=(SingletonPattern06) ois.readObject();
        ois.close();
        ObjectInputStream o1=new ObjectInputStream(new FileInputStream("src/反序列化生成多个对象.txt"));
        SingletonPattern06 s4=(SingletonPattern06) o1.readObject();
        o1.close();
        System.out.println(s3);
        System.out.println(s4);

com.fgy.singleton.SingletonPattern06@152b6651
com.fgy.singleton.SingletonPattern06@6abf2d5e
com.fgy.singleton.SingletonPattern06@2d3bad12

解决方法:\color{red}{↓}单例模式方法类中添加使用readresolve()方法\color{red}{↓}

    private Object readResolve() throws ObjectStreamException{
        return st2;
    }

再次重新运行,就ok了

完整版的singletonPattern06类如下:

import java.io.ObjectStreamException;
import java.io.Serializable;

/**
 * 测试懒汉式(如何防止反射和反序列化)
 * @author admin
 *
 */

public class SingletonPattern06 implements Serializable{
    
    private static SingletonPattern06 st2;
    
    private SingletonPattern06(){
        if(st2!=null){
            throw new RuntimeException("防止反射漏洞");
        }
    }
    
    public static synchronized SingletonPattern06 getInstance(){
        if(st2==null){
            return st2=new SingletonPattern06();
        }
        return st2;
    }
    
    private Object readResolve() throws ObjectStreamException{
        return st2;
    }
    
}

相关文章

网友评论

      本文标题:【设计模式】——单例模式_防止反射和反序列化的漏洞

      本文链接:https://www.haomeiwen.com/subject/lpqhxktx.html