1. 簡(jiǎn)介
在Spring系列產(chǎn)品中败去,SpEL是表達(dá)式計(jì)算的基礎(chǔ)放航,實(shí)現(xiàn)了與Spring生態(tài)系統(tǒng)所有產(chǎn)品無縫對(duì)接。Spring框架的核心功能之一就是通過依賴注入的方式來管理Bean之間的依賴關(guān)系圆裕,而SpEL可以方便快捷的對(duì)ApplicationContext中的Bean進(jìn)行屬性的裝配和提取广鳍。由于它能夠在運(yùn)行時(shí)動(dòng)態(tài)分配值荆几,因此可以為我們節(jié)省大量Java代碼。
spEL表達(dá)式有很多特效:
- 使用Bean的ID來引用Bean赊时;
- 可調(diào)用方法和訪問對(duì)象屬性
- 可對(duì)值進(jìn)行算數(shù)吨铸、關(guān)系和邏輯運(yùn)算;
- 可使用正則表達(dá)式進(jìn)行匹配祖秒;
- 可進(jìn)行集合操作诞吱;
2. spEL安全漏洞
spEL表達(dá)式是可以操作類和方法的,可以通過類型表達(dá)式T(Type)來調(diào)用任意類方法竭缝,這是因?yàn)樵诓恢付?code>EvaluationContext的情況下默認(rèn)采用StandardEvaluationContext
房维,而它包含了spEL的所有功能,在允許用戶控制輸入的情況下可以造成任意命令執(zhí)行抬纸。
public static void main(String[] args) throws Exception {
//表達(dá)式咙俩。。湿故。
String spel = "T(java.lang.Runtime).getRuntime().maxMemory()";
ExpressionParser parser = new SpelExpressionParser();
Expression expression = parser.parseExpression(spel);
System.out.println(expression.getValue());
}
例如這個(gè)例子暴浦,執(zhí)行用戶傳入的任意命令,但當(dāng)用戶傳入T(java.lang.Runtime).getRuntime().maxMemory()
表達(dá)式后便會(huì)執(zhí)行某些方法晓锻,存在spEL表達(dá)式注入的安全風(fēng)險(xiǎn)。
3. 防御方法
最直接的防御方法就是使用SimpleEvaluationContext
替換StandardEvaluationContext
飞几。
官方文檔:SimpleEvaluationContext的API官方文檔
private static void test3() {
//執(zhí)行shell腳本
String spel = "T(java.lang.Runtime).getRuntime().maxMemory()";
ExpressionParser parser = new SpelExpressionParser();
Student student = new Student();
//只讀屬性
EvaluationContext context = SimpleEvaluationContext.forReadOnlyDataBinding().build();
//綁定數(shù)據(jù)
// context.setVariable("student", student);
Expression expression = parser.parseExpression(spel);
System.out.println(expression.getValue(context));
}
SimpleEvaluationContext和StandardEvaluationContext是SpEL提供的兩個(gè)EvaluationContext:
- SimpleEvaluationContext?- 針對(duì)不需要SpEL語(yǔ)言語(yǔ)法的全部范圍并且應(yīng)該受到有意限制的表達(dá)式類別砚哆,公開SpEL語(yǔ)言特性和配置選項(xiàng)的子集。
- StandardEvaluationContext?- 公開全套SpEL語(yǔ)言功能和配置選項(xiàng)屑墨。您可以使用它來指定默認(rèn)的根對(duì)象并配置每個(gè)可用的評(píng)估相關(guān)策略躁锁。
SimpleEvaluationContext旨在僅支持SpEL語(yǔ)言語(yǔ)法的一個(gè)子集,不包括 Java類型引用卵史、構(gòu)造函數(shù)和bean引用战转;而StandardEvaluationContext是支持全部SpEL語(yǔ)法的。
相關(guān)文章
spEL—基礎(chǔ)語(yǔ)法+注解中動(dòng)態(tài)調(diào)用Bean方法
spEL表達(dá)式—讓注解更加靈活(項(xiàng)目埋點(diǎn)實(shí)戰(zhàn))