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

 更新时间:2019年04月09日 09:09:17   作者:da_kao_la  
这篇文章主要介绍了单例模式的反射漏洞和反序列化漏洞,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧

除了枚举式单例模式外,其余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<SingletonLazy> cls = (Class<SingletonLazy>) Class.forName("singleton.SingletonLazy");		// 获取SingletonLazy类
		Constructor<SingletonLazy> 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");	// 文件输出流
		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.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;
	}
}

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

相关文章

  • Maven Plugins报错的解决方法

    Maven Plugins报错的解决方法

    本文主要介绍了Maven Plugins报错的解决方法,文中通过图文介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2024-02-02
  • idea将maven项目改成Spring boot项目的方法步骤

    idea将maven项目改成Spring boot项目的方法步骤

    这篇文章主要介绍了idea将maven项目改成Spring boot项目的方法步骤,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2020-09-09
  • 使用idea的database模块绘制数据库er图的方法

    使用idea的database模块绘制数据库er图的方法

    这篇文章主要介绍了使用idea的database模块绘制数据库er图,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2021-07-07
  • Java使用@Validated注解进行参数验证的方法

    Java使用@Validated注解进行参数验证的方法

    这篇文章主要介绍了Java使用@Validated注解进行参数验证的方法,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2019-08-08
  • Java中有界队列的饱和策略(reject policy)原理解析

    Java中有界队列的饱和策略(reject policy)原理解析

    这篇文章主要介绍了Java中有界队列的饱和策略(reject policy)原理解析,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
    2020-04-04
  • 获取Spring当前配置的两种方式

    获取Spring当前配置的两种方式

    这篇文章主要给大家介绍了获取Spring当前配置的,两种方式文中通过代码示例给大家介绍的非常详细,对大家的学习或工作有一定的帮助,需要的朋友可以参考下
    2024-01-01
  • 关于springboot中对sqlSessionFactoryBean的自定义

    关于springboot中对sqlSessionFactoryBean的自定义

    这篇文章主要介绍了springboot中对sqlSessionFactoryBean的自定义方式,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2021-12-12
  • JAVA OOM内存溢出问题深入解析

    JAVA OOM内存溢出问题深入解析

    这篇文章主要为大家介绍了JAVA OOM内存溢出问题深入解析,在生产环境抢修中,我们经常会碰到应用系统java内存OOM的情况,这个问题非常常见,今天我们就这个问题来深入学习探讨一下
    2023-10-10
  • MyBatis 使用权威指南

    MyBatis 使用权威指南

    MyBatis 是支持定制化 SQL、存储过程以及高级映射的优秀的持久层框架。MyBatis 避免了几乎所有的 JDBC 代码和手动设置参数以及获取结果集,本文给大家介绍MyBatis 使用指南,一起看看吧
    2017-03-03
  • CMD运行Intellij Idea编译后的class文件操作

    CMD运行Intellij Idea编译后的class文件操作

    这篇文章主要介绍了CMD运行Intellij Idea编译后的class文件操作,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2021-02-02

最新评论