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

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

作者: 从不打小怪兽 | 来源:发表于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