加入收藏 | 设为首页 | 会员中心 | 我要投稿 湖南网 (https://www.hunanwang.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 建站 > 正文

Java代码审计之SpEL表达式注入

发布时间:2019-03-14 12:35:46 所属栏目:建站 来源:Lateink
导读:一、SpEL 表达式注入 Spring Expression Language(简称 SpEL)是一种成果强盛的表达式说话、用于在运行时查询和操纵工具图;语法上相同于 Unified EL,但提供了更多的特征,出格是要领挪用和根基字符串模板函数。SpEL 的降生是为了给 Spring 社区提供一种能

类范例表达式:行使”T(Type)”来暗示 java.lang.Class 实例,”Type”必需是类全限命名,”java.lang”包除外,即该包下的类可以不指定包名;行使类范例表达式还可以举办会见类静态要领及类静态字段。

详细行使要领:

  1. ExpressionParser parser = new SpelExpressionParser(); 
  2.         // java.lang 包类会见 
  3. Class<String> result1 = parser.parseExpression("T(String)").getValue(Class.class); 
  4. System.out.println(result1); 
  5.         //其他包类会见 
  6. String expression2 = "T(java.lang.Runtime).getRuntime().exec('open /Applications/Calculator.app')"; 
  7. Class<Object> result2 = parser.parseExpression(expression2).getValue(Class.class); 
  8. System.out.println(result2); 
  9.         //类静态字段会见 
  10. int result3 = parser.parseExpression("T(Integer).MAX_VALUE").getValue(int.class); 
  11. System.out.println(result3); 
  12.         //类静态要领挪用 
  13. int result4 = parser.parseExpression("T(Integer).parseInt('1')").getValue(int.class); 
  14. System.out.println(result4); 
  • 类实例化:类实例化同样行使 java 要害字「new」,类名必需是全限命名,但 java.lang 包内的范例除外,如 String、Integer。
  • instanceof 表达式:SpEL 支持 instanceof 运算符,跟 Java 内行使同义;如”‘haha’ instanceof T(String)”将返回 true。
  • 变量界说以及引用:变量界说通过 EvaluationContext 接口的 setVariable(variableName, value) 要领界说;在表达式中行使”#variableName”引用;除了引用自界说变量,SpE 还应承引用根工具及当前上下文工具,行使”#root”引用根工具,行使”#this”引用当前上下文工具;
  • 自界说函数:今朝只支持类静态要领注册为自界说函数;SpEL 行使 StandardEvaluationContext 的 registerFunction 要领举办注册自界说函数,着实完全可以行使 setVariable 取代,两者其收??是一样的

四、审计进程

这里拿 Spring Message 长途呼吁执行裂痕来作为例子

1. 情形搭建

  1. git clone https://github.com/spring-guides/gs-messaging-stomp-websocket 
  2. git checkout 6958af0b02bf05282673826b73cd7a85e84c12d3 

拿到项目代码,全局搜刮一下 org.springframework.expression.spel.standard,发明 DefaultSubscriptionRegistry.java 文件处有导入。

Java代码审计之SpEL表达式注入

再搜刮一下 SpelExpressionParser

往下跟进发明如下要害代码,详细说明看代码注释

  1. @Override 
  2. protected void addSubscriptionInternal( 
  3. String sessionId, String subsId, String destination, Message<?> message) { 
  4. Expression expression = null; 
  5. MessageHeaders headers = message.getHeaders(); 
  6.         // 这里可以看出 SpEL 表达式 expression 是从 headers 中的 selector 字段中取出来 
  7. String selector = SimpMessageHeaderAccessor.getFirstNativeHeader(getSelectorHeaderName(), headers); 
  8. if (selector != null) { 
  9. try { 
  10.                 //天生 expression 工具 
  11. expression = this.expressionParser.parseExpression(selector); 
  12. this.selectorHeaderInUse = true; 
  13. if (logger.isTraceEnabled()) { 
  14. logger.trace("Subscription selector: [" + selector + "]"); 
  15. catch (Throwable ex) { 
  16. if (logger.isDebugEnabled()) { 
  17. logger.debug("Failed to parse selector: " + selector, ex); 
  18.         // expression 传入 addSubscription 这个函数内里,即存放在 this.subscriptionRegistry 
  19. this.subscriptionRegistry.addSubscription(sessionId, subsId, destination, expression); 
  20. this.destinationCache.updateAfterNewSubscription(destination, sessionId, subsId); 

再搜刮一下 this.subscriptionRegistry,,看看有没有挪用传进去的 expression。

(编辑:湖南网)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

热点阅读