SpringCloudFunction是一个SpringBoot开发的Servless中间件(FAAS),支持基于SpEL的函数式动态路由。在特定配置下,3 <= 版本 <= 3.2.2(commit dc5128b之前)存在SpEL表达式执行导致的RCE。

补丁分析

main分支commit dc5128b中,新增了SimpleEvaluationContext

isViaHeader变量作为flag,在解析前判断spring.cloud.function.routing-expression的值是不是取自HTTP头,如果是的话就用SimpleEvaluationContext解析SpEL语句,不是来自外部输入时(比如System.setProperty)才用StandardEvaluationContext解析。

同样的,官方测试用例已经清楚地写明了漏洞位置与Payload:

提取出测试类后在apply方法下断并跟入,省略一些中间流程,最终可以看到从HTTP头spring.cloud.function.routing-expression中取出SpEL表达式并由StandardEvaluationContext解析:

至此source与sink已经清晰,虽然测试用例可以模拟触发漏洞,但还是要搭出一套能实际复现的环境。刚开始时想不开,自己在那啃文档碎碎写了一两个小时demo硬是搭不起来,后来发现官方提供的sample就很好用Orz:

后话

好消息是只有Spring Cloud Function部分版本特定配置的动态路由才会受影响(spring.cloud.function.definition=functionRouter,坏消息是SpEL表达式存在charset、replace等多种变形。

更新

https://twitter.com/phithon_xg/status/1511760497179193346

参考链接

Function Routing and Filtering

Vanilla Spring Cloud Function with Routing