美文网首页设计模式
C05 单例模式 Enum枚举单例(一) 抗序列化攻击分析

C05 单例模式 Enum枚举单例(一) 抗序列化攻击分析

作者: 乌鲁木齐001号程序员 | 来源:发表于2019-03-05 12:26 被阅读13次

    枚举单例的抗序列化攻击演示(一)

    public enum EnumInstance {
    
        INSTANCE;
    
        private Object data;
    
        public Object getData() {
            return data;
        }
    
        public void setData(Object data) {
            this.data = data;
        }
    
        public static EnumInstance getInstance() {
            return INSTANCE;
        }
    
    }
    
    import java.io.*;
    
    public class Test {
    
        public static void main(String[] args) throws Exception {
            serializableAttack();
        }
    
        public static void serializableAttack() throws Exception {
            EnumInstance instance = EnumInstance.getInstance();
    
            ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("enum_singleton_file"));
            oos.writeObject(instance);
    
            File file = new File("enum_singleton_file");
            ObjectInputStream ois = new ObjectInputStream(new FileInputStream(file));
    
            EnumInstance newInstance = (EnumInstance)ois.readObject();
    
            System.out.println(instance);
            System.out.println(newInstance);
            System.out.println(instance == newInstance);
        }
    
    }
    

    输出:

    INSTANCE
    INSTANCE
    true

    枚举单例的抗序列化攻击演示(二)

    • 持有date的单例枚举实例;
    public class Test {
    
        public static void main(String[] args) throws Exception {
            serializableAttack2();
        }
    
        public static void serializableAttack2() throws Exception {
            EnumInstance instance = EnumInstance.getInstance();
            instance.setData(new Object());
    
            ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("enum_singleton_file"));
            oos.writeObject(instance);
    
            File file = new File("enum_singleton_file");
            ObjectInputStream ois = new ObjectInputStream(new FileInputStream(file));
    
            EnumInstance newInstance = (EnumInstance)ois.readObject();
    
            System.out.println(instance.getData());
            System.out.println(newInstance.getData());
            System.out.println(instance.getData() == newInstance.getData());
            System.out.println(instance == newInstance);
        }
    
    }
    

    输出:

    java.lang.Object@14514713
    java.lang.Object@14514713
    true
    true

    枚举单例抗序列化攻击源码分析

    • 在反序列化的时候,通过描述符desc拿到了待反序列化的枚举(EnumInstance)的Class类型c1;
    • readString(false) 又拿到了待序列化的枚举类中枚举实例(INSTANCE)的名字name;
    • 根据Enum.valueOf(Class, String) 就可以取到 EnumInstance 中的 INSTANCE 实例,其原理类似于 readResolve() 方法的添加;


      1.png

    相关文章

      网友评论

        本文标题:C05 单例模式 Enum枚举单例(一) 抗序列化攻击分析

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