单例模式的反射漏洞和反序列化漏洞代码实例

网友投稿 416 2023-01-09


单例模式的反射漏洞和反序列化漏洞代码实例

除了枚举式单例模式外,其余4种在单例模式提到的单例模式的实现方式都存在反射漏洞和反序列化漏洞。

package singleton;

import java.io.FileInputStream;

import java.io.FileOutputStream;

import java.io.ObjectInputStream;

import java.io.ObjectOutputStream;

import java.lang.reflect.Constructor;

/**

* 用反射和反序列化的方法破解单例模式

* @author weiyx15

*

*/

public class SingletonCrack {

public static void main(String[] args) throws Exception

{

// 正常创建单例对象

SingletonLazy s1 = SingletonLazy.getInstance();

SingletonLazy s2 = SingletonLazy.getInstance();

System.out.println(s1);

System.out.println(s2);

// 用反射破解单例

Class cls = (Class) Class.forName("singleton.SingletonLazy"); // 获取SingletonLazy类

Constructor cons = cls.getDeclaredConstructor(null); // 获取SingletonLazy的构造方法

cons.setAccessible(true); // 跳过方法的可见性检查

SingletonLazy s3 = cons.newInstance(); // 调用构造方法生成新对象

SingletonLazy s4 = cons.newInstance(); // 调用构造方法生成新对象

System.out.println(s3);

System.out.println(s4);

// 用反序列化破解单例

FileOutputStream fos = new FileOutputStream("object.out"); // DKTPSPZX文件输出流

ObjectOutputStream oos = new ObjectOutputStream(fos); // 对象输出流

oos.writeObject(s1); // 向文件序列化对象

oos.close(); // 关闭对象输出流

fos.close(); // 关闭文件输出流

FileInputStream fis = new FileInputStream("object.out"); // 文件输入流

ObjectInputStream ois = new ObjectInputStream(fis); // 对象输入流

SingletonLazy s5 = (SingletonLazy) ois.readObject(); // 从文件反序列化对象

ois.close(); // 关闭对象输入流

fis.close(); // 关闭文件输入流

System.out.println(s5);

}

}

运行结果

singleton.SingletonLazy@15db9742 // s1

singleton.SingletonLazy@15db9742// s2

singleton.SingletonLazy@6d06d69c// s3

singleton.SingletonLazy@7852e922// s4

singleton.http://SingletonLazy@3b07d329 // s5

从运行结果可以看到,通过反射可以得到私有构造方法,从而实例化两个不同的对象实例 codesingleton.SingletonLazy@6d06d69c}和{@code singleton.SingletonLazy@7852e922}. 通过反序列化,也可以得到新对象{@code singleton.SingletonLazy@3b07d329}.

以懒汉式单例模式的实现为例,解决反射漏洞和反序列化漏洞的方法如下:

package singleton;

import java.io.ObjectStreamException;

import java.io.Serializable;

/**

* 排除了反射漏洞和反序列化漏洞的懒汉式单例模式

* @author weiyx15

*

*/

public class SingletonLazySafe implements Serializable{

private static SingletonLazySafe instance;

private SingletonLazySafe() {

// 防止反射漏洞通过再次调用私有构造方法实例化新的instance

if (instance != null)

{

throw new RuntimeException(); // 抛出运行时异常

}

}

public static synchronized SingletonLazySafe getInstance() {

if (instance == null) // 如果未实例化,则先实例化

{

instance = new SingletonLazySafe(); // 调用getInstance方法后再实例化对象

}

return instance;

}

/**

* 从I/O流读取对象时会调用readResolve接口

* 在readResolve接口中直接返回instance对象

* 避免反序列化时重新实例化对象

* @return 单例对象

* @throws ObjectStreamException

*/

private Object readResolve() throws ObjectStreamException {

return instance;

}

}

以上所述是给大家介绍的单例模式的反射漏洞和反序列化漏洞详解整合,希望对大家有所帮助,如果大家有任何疑问请给我留言,会及时回复大家的。在此也非常感谢大家对我们网站的支持!


版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。

上一篇:详解java_ 集合综合案例:斗地主
下一篇:详解Java基础篇
相关文章

 发表评论

暂时没有评论,来抢沙发吧~