SPEL表达式及注入漏洞

SPEL,全称为Spring表达式语言,是一个由 Spring 框架提供的表达式语言。它是一种基于字符串的表达式语言,可以在运行时对对象进行查询和操作。

SpEL 支持在XML和注解配置中使用,它可以在Spring框架的各种组件中使用,如Spring MVC 控制器、Spring Security 安全框架、Spring Data 数据访问框架等。它可以方便地访问对象的属性、调用对象的方法、进行数学运算、逻辑运算、正则表达式匹配等操作。

使用 SpEL 可以大大简化编程工作,使得配置和编写代码更加灵活和易于维护。例如,可以使用 SpEL 在 XML 或注解中配置 Spring bean 的属性,或在 Spring MVC 控制器中动态地计算请求参数。总而言之,SpEL 是 Spring 框架中一个非常有用的特性,它提供了一种灵活、简洁的方式来操作和查询对象。

SpEL 表达式语言支持以下功能:

  • Literal expressions(字面量表达式)
  • Boolean and relational operators(布尔和关系运算符)
  • Regular expressions(正则表达式)
  • Class expressions(类表达式)
  • Accessing properties, arrays, lists, maps(访问属性、数组、列表、映射)
  • Method invocation(调用方法)
  • Relational operators(关系运算符)
  • Assignment(赋值运算符)
  • Calling constructors(调用构造函数)
  • Bean references(Bean 引用)
  • Array construction(数组构造)
  • Inline lists(内联列表)
  • Ternary operator(三目运算符)
  • Variables(变量)
  • User defined functions(用户定义的函数)
  • Collection projection(集合投影)
  • Collection selection(集合选择)
  • Templated expressions(模板表达式)

SPEL基础

2.1、类型表达式

在SPEL中,使用 #{} 界定符被认为是SpEL表达式,可以使用相关变量、属性和方法等操作

2.2、类型表达式

T(type)用于获取一个类型的class对象。它的作用是让SpEL表达式在运行时获取指定的类型的Class对象,以便在表达式中可以使用该类的方法属性。

使用T(type)的语法格式为:T(package,ClassName),其中package是指类所在的包名,ClassName是类名,例如,要获取java.lang.String类的class对象,可以使用表达式T(java.lang.String)。

在SpEl中,同样可以使用T(type)来调用静态方法和属性,例如:T(java.lang.Math).PI表示获取Math类中的PI静态属性,T(java.lang.Math).random() 表示调用 Math 类中的 random() 静态方法。

需要注意的是,在使用T(type)操作符时,要确保指定的类型已经被加载,否则会抛出ClassNotFoundException异常。

2.3、SpEL 的 EvaluationContext 接口

在使用 SpEL 时,我们需要将表达式与 EvaluationContext 进行绑定,然后将表达式交给 SpEL 引擎执行。EvaluationContext 为 SpEL 引擎提供了上下文信息,使得 SpEL 引擎能够正确地解析表达式中的变量、函数等信息,从而求出表达式的结果

SimpleEvaluationContext 和 StandardEvaluationContext 都是 SpEL 提供的 EvaluationContext 的实现类

它们都提供了表达式求值所需的上下文信息,但是在具体实现方面略有不同

SimpleEvaluationContext 相对来说比较简单,它仅仅包含了变量解析器和类型转换器,不支持函数表达式。

而 StandardEvaluationContext 提供了更丰富的上下文信息,包括变量解析器、类型转换器和函数表达式等。同时, StandardEvaluationContext 还支持自定义函数和类加载器等高级功能。

通常情况下,如果只是简单的表达式求值,可以使用 SimpleEvaluationContext;如果需要使用函数表达式或自定义函数等高级功能,可以使用 StandardEvaluationContext

SPEL注入漏洞

1、漏洞注入原理

简单来说,当应用程序使用SpEL时,如果未能正确处理用户输入数据,攻击者可以在表达式中注入任意代码,并在应用程序的上下文执行它,进而造成命令执行等漏洞。

SpEL的EvaluationContext,其中StandardEvaluationContext 使用方法更加完整

因此触发SPEL注入漏洞的流程大致为:接收了用户的输入且未过滤等操作,将接收的参数使用StandardEvaluationContext来处理,并对表达式调用了getvalue()或setvalue()方法。

如上流程,后端接收了用户输入且为过滤,而攻击者精心构造攻击payload,即可实现命令执行等危险操作

2、代码示例

新建一个springboot项目,选择springweb

/*127.0.0.1:8080/spel/vul/? ex=T(java.lang.Runtime).getRuntime().exec("calc") */

package com.example.speldemo;import org.springframework.expression.EvaluationContext;
import org.springframework.expression.Expression;import org.springframework.expression.spel.standard.SpelExpressionParser;
import org.springframework.expression.spel.support.StandardEvaluationContext;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;@RestController
public class SpELdemo {/*127.0.0.1:8080/spel/vul/? ex=T(java.lang.Runtime).getRuntime().exec("calc") */@GetMapping("/spel/vuln")public String vul1(String ex){SpelExpressionParser spelExpressionParser = new SpelExpressionParser();//创建SPEL解析器//StandardEvaluationContext权限过大,可以执行任意代码,默认使用可以不指定EvaluationContext evaluationContext = new StandardEvaluationContext();//创建StandardEvaluationContext对象Expression exp = spelExpressionParser.parseExpression(ex);//解析用户传入的值return  exp.getValue(evaluationContext).toString();//使用exp.getvalue获取值}
}

经过调试发现,创建解析器,创建运行环境,解析传入值,最后获取值,上面的每一步对于触发spel注入漏洞都很重要,少一半都可能无法触发。

而关键点在于parseExpression解析步骤,我们传入的T(java.lang.Runtime).getRuntime().exec("calc") ,被解析成了SPEL表达式,在获取值的时候触发了命令执行操作。

可以在return exp.getValue(evaluationContext).toString(); 处,打个断点进行 Debug。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/738778.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

JavaScript截取字符串的几种方法

1.split() split()用于把一个字符串分割成字符串数组 stringObject.split(separator,howmany) 参数说明: separator参数:必需填。字符串或正则表达式,从该参数指定的地方分割 stringObject。 howmany参数:可选。该参数可指定返…

android 快速实现 recyclerview 的所有item 都执行动画

1.在adapter 里面重写onViewAttachedToWindow 和 onViewDetachedFromWindow 两个方法 package com.example.widget;import android.view.ViewGroup; import android.view.animation.Animation; import android.view.animation.LinearInterpolator; import android.view.animat…

L3自动驾驶的“双保险”:冗余EPS关键技术解析

摘要: 本文主要介绍冗余EPS的发展路径和关键技术。 引言 在乘用车领域,电动助力转向系统(Electric Power Steering,EPS)相比传统的液压助力转向系统(Hydraulic Power Steering,HPS)具有结构简单、响应迅速、能耗低等优点,因此应用很广。随着智能驾驶的发展,作为底层…

springboot261高校专业实习管理系统的设计和开发

基于spring boot的高校专业实习管理系统的设计与实现 摘 要 随着国内市场经济这几十年来的蓬勃发展,突然遇到了从国外传入国内的互联网技术,互联网产业从开始的群众不信任,到现在的离不开,中间经历了很多挫折。本次开发的高校专…

制造行业大数据应用:四大领域驱动产业升级与智慧发展

一、大数据应用:制造行业的智慧引擎 随着大数据技术的不断突破与普及,制造行业正迎来一场前所未有的变革。大数据应用,如同智慧引擎一般,为制造行业注入了新的活力,推动了产业升级与创新发展。 二、大数据应用在制造行…

外贸人要加油努力,到底怎么做

我们说要加油,要努力,那做外贸我们的力气到底应该往哪里使?想要把外贸做好容易吗? 其实没有一件事情背后他是真正容易的,如果发现自己迷茫了,很有可能是你既要又要,没有自己的一个满足感&#…

鸿蒙ArkTS语言快速入门-TS(二)

相关文章快速入口:鸿蒙ArkTS语言快速入门-TS(三) ArkTS入门第二篇 TS入门学习变量声明条件语句if语句switch…case 语句 接口普通函数接口函数类型接口类类型接口继承接口接口继承类 TS入门学习 变量声明 使用let和const声明,替…

Elasticsearch:机器学习与人工智能 - 理解差异

作者:来自 Elastic Aditya Tripathi, Jessica Taylor 长期以来,人工智能几乎完全是科幻小说作家的玩物,人类将技术推得太远,以至于它变得活跃起来 —— 正如好莱坞让我们相信的那样 —— 开始造成严重破坏。 令人愉快的东西&#…

C++中的RAII原则和资源管理如何提高程序效率和安全性?

文章目录 C中的RAII(Resource Acquisition Is Initialization)原则是一种编程范式,它确保资源在其生命周期内的有效管理。RAII的核心思想是在对象创建时(初始化阶段)获取资源,并在对象销毁时(析…

springboot项目集成nacos做配置中心后没生效问题

问题描述&#xff1a; springboot项目中集成nacos做配置中心&#xff0c;添加了nacos依赖和bootstrap.yaml后&#xff0c;项目启动时nacos并没有生效&#xff08;打印日志中都没有nacos相关信息&#xff09;。 <dependency><groupId>com.alibaba.cloud</groupI…

论企业安全漏洞扫描的重要性

前言 随着信息技术的迅猛发展和互联网的广泛普及&#xff0c;网络安全问题日益凸显。在这个数字化的世界里&#xff0c;无论是企业还是个人&#xff0c;都面临着前所未有的安全威胁。安全漏洞&#xff0c;作为这些威胁的源头&#xff0c;常常被忽视或无法及时发现。 而安全漏洞…

Codeforces-927(div3)-C. LR-remainders

这题很经典啊,对于除怎么解决取模的问题. 这种题确实是非常经典,就是这个取模怎么解决有除的问题呢?? 一开始,出于某种奇怪的心态(不就是日常装杯吗....),压根没考虑到.以此警醒自己,认真对待,仔细审题,仔细理解. 回归正文: 处理有除法的取模,可用线段树,就是凑区间吗,能…

ansible-playbook的角色(role)

1前言 角色目录如下&#xff08;分别为httpd角色和nginx角色&#xff09; handlers/ &#xff1a;至少应该包含一个名为 main.yml 的文件&#xff1b; 其它的文件需要在此文件中通过include 进行包含 vars/ &#xff1a;定义变量&#xff0c;至少应该包含一个名为 main.yml 的…

Leetcode 572 另一棵树的子树

文章目录 1. 题目描述2. 我的尝试3. 其他题解 1. 题目描述 Leetcode 572 另一棵树的子树 2. 我的尝试 以中序顺序从大树的根节点开始遍历&#xff0c;每次比较以当前节点为根节点的子树是否与小树相同。若某次比较结果为true&#xff0c;说明小树是大树的子树。 比较两树是…

JDK环境变量配置-jre\bin、rt.jar、dt.jar、tools.jar

我们主要看下rt.jar、dt.jar、tools.jar的作用&#xff0c;rt.jar在​%JAVA_HOME%\jre\lib&#xff0c;dt.jar和tools.jar在%JAVA_HOME%\lib下。 rt.jar&#xff1a;Java基础类库&#xff0c;也就是Java doc里面看到的所有的类的class文件。 tools.jar&#xff1a;是系统用来编…

在ubuntu上安装FastSufer【本机安装】

亲测:FastSurfer分割并重建一个大脑需要1个小时,而freeSurfer需要8个小时。确实很快! 这里我在网页端搭建了一个小的工具包,里面集成了经典的freeSurfer和较快的FastSurfer。如果你不想安装或者手头没有linux设备,您也可以直接从以下网址直接使用,跳过繁琐的安装步骤!!…

嵌入式面经-ARM体系架构-寄存器与异常处理

ARM寄存器组织 寄存器概念 寄存器是处理器内部的存储器&#xff0c;没有地址 寄存器作用 一般用于暂时存放参与运算的数据和运算结果 在某个特定模式下只能使用当前模式下的寄存器&#xff0c;一个模式下特有的寄存器别的模式下不能使用 一共是40个寄存器 寄存器分类 通用寄…

Vue3.0里为什么要用 Proxy API 替代 defineProperty API

一、Object.defineProperty 定义&#xff1a;Object.defineProperty() 方法会直接在一个对象上定义一个新属性&#xff0c;或者修改一个对象的现有属性&#xff0c;并返回此对象 为什么能实现响应式 通过defineProperty 两个属性&#xff0c;get及set get 属性的 getter 函…

Br 算法

基于google的brotli开源&#xff0c;实现Br算法。 #include <brotli/encode.h> #include <brotli/decode.h>namespace br {/*compress unsigned char* content,if ok return non empty unsigned char * */std::string compress_string(const std::string& c…

【Web】浅聊Hessian反序列化之打Rome出网不出网

目录 前言 出网——JdbcRowSetImpl 不出网——SignedObject 打二次反序列化 前文&#xff1a;【Web】浅聊Java反序列化之玩转Hessian反序列化的前置知识 前言 正如我们前文所说&#xff0c;当Hessian反序列化Map类型的对象的时候&#xff0c;会自动调用其put方法&#xff…