java 反射攻击

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

猜你喜欢

转载自tcspecial.iteye.com/blog/2380071
今日推荐