欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

java 反射攻击

程序员文章站 2022-03-03 11:49:21
...

 

Java反射机制指的是程序在运行时能够获取自身的信息;它能动态截获或改写程序的行为。

 

1. 单例模式漏洞

/**
 * 懒汉式单例模式
 */
public class Singleton {
	private static Singleton instance = null;

	private Singleton() {

	}

	public static synchronized Singleton getInstance() {
		if( instance == null ){
			instance = new Singleton();
		}

		return instance;
	}
}

 

常规情况下,只能通过 getInstance() 创建实例;但是通过反射可以直接调用private方法创建实例。

/**
 * 单例反射攻击
 */
public static void singletonTest() throws Exception {
	Class<Singleton> clazz = (Class<Singleton>)Class.forName( "com.sun.Singleton" );

	Constructor<Singleton> constructor = clazz.getDeclaredContructor( null );
	constructor.setAccessible( true );	// 允许访问私有属性,跳过权限检查

	// 成功创建多个实例
	Singleton s1 = constructor.newInstance();
	Singleton s2 = constructor.newInstance();
}

 解决方案:在无参构造函数中再次检测instance是否存在。

 

2. 泛型漏洞

面试题:

给一个ArrayList<Integer>的一个对象,要在这个集合中添加一个字符串数据,如何实现呢?

大家都知道,泛型约束了集合的数据类型,添加非Integer数据会引起编译错误。

 

/**
 * 反射突破泛型检测
 */
public static void addString() throws Exception {
	List<Integer> list = new ArrayList<Integer>();
	list.add( 1 );
	
	// Get class
	Class<? extends List> clazz = list.getClass();
	// Get add method
	Method method = clazz.getMethod( "add", Object.class );

	// invoke 
	Object obj = method.invoke( list,  "str1" );
	obj = method.invoke( list, "str1" );
	obj = method.invoke( list, "str2" );
	
	// print
	for( Object i : list ){
		System.out.println( "Val: " + i );
	}
}

 

上述代码成功绕开泛型检测,执行结果如下:

Val: 1

Val: str1

Val: str2

 

 

 

 

 

相关标签: java 反射