背景介绍
最近各大网站相继发出了漏洞预警信息,Spring Cloud Function 从3.0.0.RELEASE 到3.2版本都存在一个表达式注入漏洞,目前尚未发布新的修复版本。目前从官方补丁https://github.com/spring-cloud/spring-cloud-function/commit/0e89ee27b2e76138c16bcba6f4bca906c4f3744f ,目前POC也已经公开了。
从补丁中可以看的出来其实开发者已经把sink点写出来了,因此主要是能够找到Source点。
具体漏洞分析可以参考下面的文章,我就不再赘述了。
@默安逐日实验室 https://mp.weixin.qq.com/s/ssHcLC72wZqzt-ei_ZoLwg ,需要在boot的配置文件中增加下面的代码
spring.cloud.function.definition=functionRouter
然后使用POC,请求任意路径(包括不存在的)都可以触发;
以及
@pen4uin https://mp.weixin.qq.com/s/U7YJ3FttuWSOgCodVSqemg 提出不改变默认配置文件下的请求特定路由地址 POST /functionRouter 下依然能否触发。
其实上面找到的两个Source 点都是有一个前提条件的,就是必须满足org.springframework.cloud.function.context.catalog.SimpleFunctionRegistry.FunctionInvocationWrapper#doApply 方法中 isRoutingFunction() 条件,如果满足这个条件才会进入到
result = ((Function)this.target).apply(convertedInput);
这里是触发SPEL 解析的重要一步。
Object doApply(Object input) {
input = this.fluxifyInputIfNecessary(input);
Object convertedInput = this.convertInputIfNecessary(input, this.inputType);
Object result;
if (!this.isRoutingFunction() && !this.isComposed()) {
if (this.isSupplier()) {
result = ((Supplier)this.target).get();
} else if (this.isConsumer()) {
result = this.invokeConsumer(convertedInput);
} else {
result = this.invokeFunction(convertedInput);
}
} else {
result = ((Function)this.target).apply(convertedInput);
}
return result;
}
看下isRoutingFunction()代码:
public boolean isRoutingFunction() {
return this.target instanceof RoutingFunction;
}
看下 RoutingFunction 原型是实现了 Function 接口,输入和输出参数都要求是Object类。
因此如果代码里function方法参数是字符型等非Object的话,即使配置文件里配置了functionRouter
spring.cloud.function.definition=functionRouter
也是无法执行恶意代码的
public static class RoutingFunctionConfiguration {
public Function<String, String> echo() {
return x -> {
System.out.println("===> echo");
return x+" echo function";
};
}
但是这样写那就会受此漏洞影响
public Function<Person, Person> pojoecho() {
return x -> {
System.out.println("===> pojoecho");
return x;
};
}
private static class Person {
private String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
以为这样就结束了,但是发现pen4uin 的文章里 提到的路由 不论代码是怎么配置的,都能够触发SPEL表达式执行。是因为这个路由最终会绑定到RoutingFunction,因此满足isRoutingFunction() 条件。
其实 /functionRouter/ 后面跟任意路径都是可以的,例如
/functionRouter/aaa
甚至 /functionRouter/aaa/bbb
修复方案
临时方案:
-
添加 /functionRouter 路径黑名单,注意路径绕过问题。并检查配置文件
也可参考官方补丁,重新打包
参考文章
https://mp.weixin.qq.com/s/ssHcLC72wZqzt-ei_ZoLwg
https://mp.weixin.qq.com/s/U7YJ3FttuWSOgCodVSqemg
原文始发于微信公众号(风藤安全):Spring-Cloud-Function SPEL 注入漏洞的一点想法
- 左青龙
- 微信扫一扫
-
- 右白虎
- 微信扫一扫
-
评论