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.mfbz.cn/a/450174.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

7.无重复字符的最长字串

给定一个字符串 s ,请你找出其中不含有重复字符的 最长 子串 的长度。 示例 1: 输入: s "abcabcbb" 输出: 3 解释: 因为无重复字符的最长子串是 "abc",所以其长度为 3。示例 2: 输入: s "bbbbb" 输出: 1 解释: 因为…

Flink技术简介与入门实践

架构简介 Flink 是一个分布式流处理和批处理计算框架,具有高性能、容错性和灵活性。下面是 Flink 的架构概述: JobManager:JobManager 是 Flink 集群的主节点,负责接收和处理用户提交的作业。JobManager 的主要职责包括&#xff1…

【wps】wps与office办公函数储备使用(结合了使用案例 持续更新)

【wps】wps与office办公函数储备使用(结合了使用案例 持续更新) 1、TODAY函数 返回当前电脑系统显示的日期 TODAY函数:表示返回当前电脑系统显示的日期。 公式用法:TODAY() 2、NOW函数 返回当前电脑系统显示的日期和时间 NOW函数:表示返…

案例分析篇11:一篇文章搞定UML设计考点(2024年软考高级系统架构设计师冲刺知识点总结系列文章)

专栏系列文章推荐: 2024高级系统架构设计师备考资料(高频考点&真题&经验)https://blog.csdn.net/seeker1994/category_12593400.html 【历年案例分析真题考点汇总】与【专栏文章案例分析高频考点目录】(2024年软考高级系统架构设计师冲刺知识点总结-案例分析篇-…

【linux线程(一)】什么是线程?怎样操作线程?

💓博主CSDN主页:杭电码农-NEO💓   ⏩专栏分类:Linux从入门到精通⏪   🚚代码仓库:NEO的学习日记🚚   🌹关注我🫵带你学更多操作系统知识   🔝🔝 Linux线程 1. 前言2. 什么是线…

阻塞队列学习

1、什么是阻塞队列? 顾名思义,就是支持阻塞的队列,相比于其他的队列,阻塞队列支持以下特性: 队列为空的时候,获取元素的线程会等待队列变为非空。队列为满的时候,存储元素的线程会等待队列可以…

认证授权与JWT

认证授权与JWT 1、认证授权概念介绍1.1 什么是认证1.2 什么是授权 2、权限数据模型3、RBAC权限模型3.1 介绍3.2 基于角色访问控制3.3 基于资源访问控制 4、常见认证方式4.1 Cookie-Session4.2 jwt令牌无状态认证 5 常见技术实现6.Jwt介绍6.1 JWT简介6.2.Jwt组成 7、JWT使用7.1 …

JFMQL100TAI900/JFMQL100T900全国产化 ARM 核心板+扩展板/全国产开发板

TEC100TAI-KIT 是一款基于青龙100TAI 的全国产智能异构计算平台开发套件,该套件包含 1个 100TAI 核心板和 1 个 PCIE 规格的扩展底板。该 套 件 的 核 心 板 集 成 了 100TAI 的 最 小 系 统 , 包 含 一 颗JFMQL100TAI900 片上系统芯片,该单颗…

5、Async await(等待异步)、函数的防抖和节流、模块化

一、Async await(等待异步) Async去声明函数,返回一个promise对象,await在声明的函数里面使用 function fn_1() {return fn_1 } function fn_2() {return new Promise((reslove) > {setTimeout(() > {//因为定时器是异步的 num 10return reslov…

使用gnvm下载nodejs和npm

目录 前言 一、下载gnvm 二、利用gnvm下载nodejs 三、下载对应版本的npm 四、gnvm常用的命令 总结 前言 由于之前下载的版本过低,需要升级版本。但在使用gnvm升级node版本时遇到了一系列的问题,索性就把nodejs全部删除,重新用gnvm在下…

【保姆级教程】JDK安装与环境变量配置

文章目录 第一步:下载JDK(以1.8为例)第二步:安装第三步:找到默认安装目录第四步:配置环境变量(win10为例) 大家可能会遇到的疑问:一个电脑可以安装多个版本的jdk没有问题…

抽样算法——【数据科学与工程算法基础】

一、前言 这是课程的第二章节——抽样算法,主要分为三类。 详情可参考: 数据科学的算法基础——学习记录跳转中心 二、正篇 1.系统抽样 课本只介绍了最简单的——等距抽样。 直线等距抽样(Nn*k):即总体个数可以被抽…

swiftUI 中如何忽略safeArea

swiftUI 中如何忽略safeArea 不管是UIKit和swiftUI为了能适配更多设备,所以出来了一个safeArea的设定。那如何把我们的控件放到safeArea里面呢 答案就是ignoresSafeArea ignoresSafeArea 通过把Text空间放到一个VStack下然后给VStack设置宽高无限大,就…

如何选择合适的IP代理,如何为网络爬虫设置代理

目录 前言 1. 代理类型的选择 2. 代理速度 3. 代理稳定性 4. 代理的匿名性 5. 代理的地理位置 总结 前言 在进行网络爬虫任务时,为了避免被目标网站封禁IP或限制访问频率,我们通常会使用代理来隐藏真实的IP地址。选择合适的IP代理对于爬虫的成功…

1. DDPM模型概述

1. DDPM模型概述 扩散模型(DM,Diffusion Model)是一类生成模型,常见的生成模型还有GAN和VAE。扩散模型分为前向阶段和逆向阶段,在前向阶段中逐步向数据中添加噪声,直至数据变成完全的高斯噪声,…

Redis高可用之哨兵模式和集群模式

Redis高可用 Redis哨兵高可用 概述 sentinel哨兵是特殊的redis服务,不提供读写服务,主要用来监控redis实例节点。 哨兵架构下client端第一次从哨兵找出redis的主节点,后续就直接访问redis的主节点 不会每次都通过sentinel代理访问redis的主…

网络地址转换协议NAT

网络地址转换协议NAT NAT的定义 NAT(Network Address Translation,网络地址转换)是1994年提出的。当在专用网内部的一些主机本来已经分配到了本地IP地址(即仅在本专用网内使用的专用地址),但现在又想和因…

YOLOv8改进 | 注意力机制 | 添加YOLO-Face提出的SEAM注意力机制优化物体遮挡检测(附代码 + 修改教程)

一、本文介绍 本文给大家带来的改进机制是由YOLO-Face提出能够改善物体遮挡检测的注意力机制SEAM,SEAM(Spatially Enhanced Attention Module)注意力网络模块旨在补偿被遮挡面部的响应损失,通过增强未遮挡面部的响应来实现这一目标,其希望通过学习遮挡面和未遮挡面之间的…

Word转PDF保持图片原有清晰度

目录 1、需要的软件 2、配置Acrobat PDFMaker 3、配置Acrobat Distiller 4、更改Acrobat PDFMaker中的首选项 5、将word转换成pdf 1、需要的软件 利用Adobe Acrobat DC工具。 打开word,选择Acrobat的插件,选择首选项。 如果没有出现Acrobat插件也…

Java学习记录(十七)IO流(三)

转换流(在字节流中想使用字符流的方法时使用) 转换流是字节流和字符流之间的桥梁,转换流本身其实就是字符流所以可以使用字符流里的相关方法,通过InputStreamReader字符转换输入流能将字节流转化为字符流输入到内存中&#xff0c…