不安全的java 反射

 

不安全的java 反射_第1张图片

Description

该漏洞是因为在Java或者C#语言中使用反射机制时安全方面考虑不周所致。

攻击者可以在应用中创建开放者预料之外的控制流路径,从而可能绕过了访问控制等安全机制。对漏洞的利用可能会造成代码注入等危害。

 

Risk Factors

如果一个攻击者提供的输入用于应用确定实例化什么类或者执行什么方法,那么就有可能构造出开发者设定之外的控制流路径。精心设计的攻击向量可以帮助攻击者绕开认证或者访问控制检查,也有可能让应用以不可预料的方式活着攻击者期望的方式运作。

结合其他漏洞会让情况变得更加不可收拾,比如,攻击者如果可以上传文件到应用的classpath或者增加新的对象到应用的classpath中,那么攻击者实际上就可以执行任何恶意的代码,

 

Examples

开放人员用反射的主要原因是为了实现自己的命令分发机制。下面的代码是不实用反射的命令分发逻辑。

	String command= request.getParameter("command");
	Executor executor= null;
	if (command.equals("Add")) {
	  executor= new AddCommand();
	} else if (command.equals("Modify")) {
	  executor = new ModifyCommand();
	} else {
	  throw new UnknownCommandException();
	}
	executor.run(request);

如果用了反射重构上面的代码,可以得到更优雅简洁的代码如下

	String command = request.getParameter("command");
	Class cmdClass = Class.forName(command+ "Command");
	Executor executor = (Executor) cmdClass.newInstance();
	Executor.run(request);

重构后的代码有些显而易见的优点:代码行数变少;可读性差if-else块完全消除;以后需要增加新的命令时,不需要修改此处代码。

但是,重构后的代码允许攻击者实例化任何实现了Executor接口的任何对象。如果此命令分发器还负责访问控制,那在开发人员新增一个实现Executor接口的类时,还需兼顾修改访问控制的代码。如果他们忘记了这么做,那么新增的类就脱离了访问控制了。

处理此类访问控制问题的一个方式是让Executor对象自己负责访问控制I的检查,示例代码如下

	String command= request.getParameter("command");
	Class cmdClass = Class.forName(command+ "Command");
	Executor executor = (Executor) cmdClass.newInstance();
	executor.checkAccessControl(request);
	executor.doAction(request);

尽管这有所改善,但是这种做法放弃了集中式的访问控制管理,会增加开放人员犯错的机会。与此同时,代码还暴露了另外一个安全问题。攻击者可以调用任何兑现的默认构造器。事实上,攻击者甚至不一定要遵守实现Executor接口的约束,因为调用之前并没有任何检查。如果一个对象没有实现Executor接口,强制类型转换的赋值语句会得到一个ClassCastException异常,但是这对攻击者来说也许无所谓,因为他要干的罪恶勾当很可能在构造函数里已经全都做完了,比如对数据库里的数据已经修改完成。虽然这种情况在简单应用程序中相对来说不那么严重,但在复杂度呈指数级增长的大型应用程序中,攻击者可以找到一个构造函数作为攻击的一部分加以利用,这并非是杞人忧天。

 

识别以下二维码关注信息安全club 公众号

你可能感兴趣的:(信息安全,安全)