学习路径: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