学习路径:https://coding.imooc.com/class/270.html
前言 无论是【懒汉式】还是【饿汉式】的单例模式,不加以处理,都可以使用序列化和反序列化攻击。
攻击代码
HungrySingleton instance = HungrySingleton.getInstance(); ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("singleton_file")); // 序列化【写】操作 oos.writeObject(instance); File file = new File("singleton_file"); ObjectInputStream ois = new ObjectInputStream(new FileInputStream(file)); // 反序列化【读】操作 HungrySingleton newInstance = (HungrySingleton) ois.readObject(); System.out.println(instance); System.out.println(newInstance); System.out.println(instance == newInstance); 攻击原理jdk的源码InputStream在读对象的时候,会通过反射生成一个新的对象,而不是拿原来对象的引用。
防御方案 1.通过jdk的方法定义,告诉jdk该类反序列化的时候不要反射,而要使用自己定义的应用。
/** * 防止反序列化攻击,readResolve是源码中定义的方法名,当且仅当使用这个方法 * @return */ private Object readResolve(){ return hungrySingleton; }2.使用枚举类的单例实现
https://blog.csdn.net/chenghan_yang/article/details/90482237