JAVA安全—SpringBoot框架MyBatis注入Thymeleaf模板注入
前言
之前我们讲了JAVA的一些组件安全,比如Log4j,fastjson。今天讲一下框架安全,就是这个也是比较常见的SpringBoot框架。
SpringBoot框架
Spring Boot是由Pivotal团队提供的一套开源框架,可以简化spring应用的创建及部署。它提供了丰富的Spring模块化支持,可以帮助开发者更轻松快捷地构建出企业级应用。Spring Boot通过自动配置功能,降低了复杂性,同时支持基于JVM的多种开源框架,可以缩短开发时间,使开发更加简单和高效。
先来了解一下这个框架里面常见的东西
路由映射
@RequestMapping, @GetMapping, 和 @PostMapping 注解用于定义HTTP请求的映射路径。
@RequestMapping 是通用注解,而 @GetMapping 和 @PostMapping 是其简化形式,分别用于处理GET和POST请求。
参数传递
@RequestParam 注解用于从HTTP请求中提取参数,使得控制器方法可以访问并使用这些参数。
数据响应
@RestController 注解用于标识一个类是RESTful风格的控制器,它包含了 @ResponseBody 和 @Controller 的功能。
@ResponseBody 表示方法的返回值将直接作为HTTP响应体返回给客户端。
@Controller 通常用于标识传统的MVC控制器,而 @RestController 更适用于RESTful风格的控制器。
项目构建
新建一个项目。
这个服务器URL是默认从官网获取架构,如果说你觉得网络卡的话,你可以改为https://start.aliyun.com,去从阿里云获取架构。
版本的话目前最新的就是3.4.0了。
如果你前面用的是阿里云的架构网址,那么就会只显示2.x的版本,就是说阿里云认为这几个版本比较稳定,所以只提供这几个。
我这里网速慢,就用阿里云的2.3.16版本,依赖选择Spring Web。
创建成功之后可以看到这个框架自带了很多外部库,什么Log4j啊啥的,就不需要我们自己去下载了,比较方便。
新建一个类叫controller.IndexController。
我们写入以下代码。
package com.sf.maven.springboot.controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class IndexController {@RequestMapping("/wlw")public String index(){return "wlw";}}
接着回到Application.java这里运行起来。
此时便可以在控制台这里看到启动了8080端口也就是Tomcat服务,这是它自带的我并没有去配置它。
如果端口被占用的话,你可以在resources目录下的application.properties配置文件进行修改。
访问8080端口,返回的确是我们写入的东西。
我们稍微修改一下,添加POST请求和GET请求。
package com.sf.maven.springboot.controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class IndexController {@RequestMapping(value = "/wlwget",method = RequestMethod.GET) //get请求public String getmethod(){return "wlwget";}@RequestMapping(value = "/wlwpost",method = RequestMethod.POST) //post请求public String postmethod(){return "wlwpost";}}
我们运行起来再访问一下,可以看大此时我们再访问wlw的话会报错,这个就是典型的SpringBoot报错页面。
get提交wlwget,则是正常返回。
我们用postman这个工具去请求wlwpost,也是正常返回信息。
现在我们修改代码添加参数来试一下,稍微修改一下代码,传递参数name。
get请求。
post请求。
MyBatis注入
MyBatis是SpringBoot中用的较多的一个数据库驱动,它存在的一个安全问题就是,使用MyBatis的时候遇到了#{}和${}可能导致sql注入的问题。
先创建一个项目重新来吧,命名为MyBatis-demo。
依赖项就选择Spring web,MyBatis Framework,MySQL Driver。
数据库的话我这里是用phpstudy,简单方便,我是在user库里面新建一个user表来进行测试。
在pom文件这里可以看到,外部包都被导入了。
接着再来配置一下数据库连接,把src/main/resources/ 目录下的 application.properties文件改为application.yml
清空里面的内容。写入以下的内容。
spring:datasource:url: jdbc:mysql://localhost:3306/userusername: rootpassword: 123456driver-class-name: com.mysql.cj.jdbc.Driver
新建一个类叫entity.User。
接着我们先写入以下代码,要和数据库的字段对应。
然后右键选择生成,选择Setter和Getter,把显示的三个东西都选上确定即可。
自动生成了方法代码。
同理选择toStron()方法自动生成。
再新建一个类叫mapper.Usermapper。
写入以下的代码,创建sql查询的接口。
package com.sf.maven.mybatisdemo.mapper;import com.sf.maven.mybatisdemo.entity.User;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Select;import java.util.List;@Mapper
public interface Usermapper {// ${id} 是拼接写法,#{id} 是预编译写法@Select("select * from name")//通过ID查询public List<User> findAll();@Select("select * from name where ID=1")public List<User> findID();
}
同理再创建一个constroller类去调用我们的sql查询,新建一个类叫constroller.Getnamecontroller,
这个和上面的那个 web 应用访问一样,就是返回数据为从数据库获取信息。
package com.sf.maven.mybatisdemo.constroller;
import com.sf.maven.mybatisdemo.entity.User;
import com.sf.maven.mybatisdemo.mapper.Usermapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import java.util.List;@RestController
public class Getnamecontroller {@Autowiredprivate Usermapper Usermapper;@GetMapping("/Getpasswd")//定义请求路径public List<User> getpasswd(@RequestParam Integer id) {List<User> all = Usermapper.findAll();//调用sql查询接口return all;}@GetMapping("/GetID")public List<User> getID() {List<User> all = Usermapper.findID();return all;}}
把搞好的项目运行起来,访问路径可以查看到表的内容,说明是执行了我们设定好的sql语句。
接下来就讲一下产生的安全问题,改一下刚才的代码。
运行起来访问一下,这次要加上参数才可以进行查询。
我们设置的sql语句是 select * from name where id like '%${id}%',此时我们只要把 id=1 的查询改为 id=1%' or 1=1# 即可产生sql注入,这是因为当参数拼接上去之后sql语句就变成这样子了
select * from name where id like '%1%' or 1=1#' 。
只是不知道为啥我这里会报错,sql语句没问题呀。
我索性去到数据库那里试一下,发现是可以执行没有报错,你妹的。
关于为啥会产生sql注入,可以看一下这篇文章,在Java中呢,sql注入是非常少的,但是不代表没有。
Mybatis 框架下 SQL 注入攻击的 3 种方式,真是防不胜防! - 知乎
【安全】mybatis中#{}和${}导致sql注入问题及解决办法_${}sql注入-CSDN博客
Thymeleaf模板注入
我们在浏览一些网站时,会发现有些网站的页面十分的精美,这是由于网站开发引用了一些模板。而在SpringBoot中,Thymeleaf是个不安全的模版,日常开发中语言切换页面,主题更换等传参导致的 SSTI 注入安全问题。
新建一个项目叫Thymeleaf demo。
依赖项选择Thymeleaf和Spring web。
新建一个类叫controller.thymeleafcontroller。
我们写入个比较简单的代码,什么意思呢,就是访问index,由于我没有使用模板渲染那么就会返回个Hello World。
运行起来访问index,确实返回了Hello World,我这里就比较简陋的测试一下,实际情况中一般都是十分精美的页面。
那么现在我们使用一下模板渲染,在配置文件中可以看到模板的路径为templates/。
我们在resources目录下新建一个templates目录。
写一个index.html文件当作模板。
修改一下调用文件,调用我们的index模板并输出hello wlw。
运行代码访问index,然而却并没有返回hello wlw,而是返回了index。
这是为啥呢,原来是@RestController包含了 @ResponseBody 和 @Controller 的功能。@ResponseBody index当做字符串显示操作,所以我们更换为@Controller 没有ResponseBody index那么就会当做资源文件去渲染。
改了之后再访问返回了hello wlw,说明成功调用了模板。
查看页面源码,发现和我们写的index.html文件差不多。
OK那么我们现在来看一下安全问题,上面我们说过安全问题就是由于模板的调用,我们可以看到当前的lang=ZH_CN就是调用了中文页面的模板。
当我们把lang的值换为en那么就会调用英文的模板,思考一下我们把lang的值换位Java代码是否能实现rce。
注入漏洞存在与3.0.0—3.0.11版本,2.x版本的应该也会存在漏洞,但是我们的这个包是从阿里云拉取的。阿里云的东西一般都比较稳定没啥漏洞,我们替换一下pom文件。
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"><modelVersion>4.0.0</modelVersion><groupId>org.springframework</groupId><artifactId>java-spring-thymeleaf</artifactId><version>1.0</version><parent><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-parent</artifactId><!--latest--><version>2.2.0.RELEASE</version></parent><dependencies><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-thymeleaf</artifactId></dependency></dependencies><properties><java.version>1.8</java.version></properties><build><plugins><plugin><groupId>org.springframework.boot</groupId><artifactId>spring-boot-maven-plugin</artifactId></plugin></plugins></build>
</project>
替换了之后我们可以看到版本变为了2.2.0release。
稍微修改一下调用文件,使其可以传递参数lang。
我们再新建一个index-en.html模板文件,啥也不用写。
运行代码访问啥也没有,因为我们模板啥也没写。
把index-en换成下面的Java代码,成功弹出计算机。
__$%7bnew%20java.util.Scanner(T(java.lang.Runtime).getRuntime().exec(%22calc%22).getInputStream()).next()%7d__::.x
至于poc怎么构造的后面有机会再说了,或者看一下以下文章。
thymeleaf模板注入学习与研究--查找与防御
Thymeleaf模板生成过程以及注入原因分析 - 先知社区
总结
本次从开发的方面讲了两个SpringBoot框架常见的安全问题,感觉有点强度了,哎。
最后,以上仅为个人的拙见,如何有不对的地方,欢迎各位师傅指正与补充,有兴趣的师傅可以一起交流学习。
相关文章:

JAVA安全—SpringBoot框架MyBatis注入Thymeleaf模板注入
前言 之前我们讲了JAVA的一些组件安全,比如Log4j,fastjson。今天讲一下框架安全,就是这个也是比较常见的SpringBoot框架。 SpringBoot框架 Spring Boot是由Pivotal团队提供的一套开源框架,可以简化spring应用的创建及部署。它提…...

【STM32系列】提升ADC采样精度的方法
资料地址 兆易创新GigaDevice-资料下载兆易创新GD32 MCU ADC简介 ADC转换包括采样、保持、量化、编码四个步骤。的采样电容上,即在采样开关 SW 关闭的过程中,外部输入信号通过外部的输入电阻 RAIN 和以及 ADC 采样电阻 RADC 对采样电容 CADC 充电。采样…...

前端面试如何出彩
1、原型链和作用域链说不太清,主要表现在寄生组合继承和extends继承的区别和new做了什么。2、推荐我的两篇文章:若川:面试官问:能否模拟实现JS的new操作符、若川:面试官问:JS的继承 3、数组构造函数上有哪些…...
Linux 切换用户的两种方法
sudo -su user1 与 su - user1 都可以让当前用户切换到 user1 的身份执行命令或进入该用户的交互式 Shell。但它们在权限认证方式、环境变量继承和 Shell 初始化过程等方面存在一些差异。 权限认证方式 su - user1 su 是 “switch user” 的缩写,默认情况下需要你输…...

Spring Boot 3 中Bean的配置和实例化详解
一、引言 在Java企业级开发领域,Spring Boot凭借其简洁、快速、高效的特点,迅速成为了众多开发者的首选框架。Spring Boot通过自动配置、起步依赖等特性,极大地简化了Spring应用的搭建和开发过程。而在Spring Boot的众多核心特性中ÿ…...

Vue实现留言板(实现增删改查)注意:自己引入Vue.js哦
代码: <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><meta name"viewport" content"widthdevice-width, initial-scale1.0"><title>Document</title><scri…...

IDEA创建Spring Boot项目配置阿里云Spring Initializr Server URL【详细教程-轻松学会】
1.首先打开idea选择新建项目 2.选择Spring Boot框架(就是选择Spring Initializr这个) 3.点击中间界面Server URL后面的三个点更换为阿里云的Server URL Idea中默认的Server URL地址:https://start.spring.io/ 修改为阿里云Server URL地址:https://star…...

读取电视剧MP4视频的每一帧,检测出现的每一个人脸并保存
检测效果还不错,就是追踪有点难做 import cv2 import mediapipe as mp import os from collections import defaultdict# pip install msvc-runtime# 初始化OpenCV的MultiTracker # multi_tracker = cv2.MultiTracker_create() # multi_tracker = cv2.legacy.MultiTracker_cre…...

HTML前端开发-- Iconfont 矢量图库使用简介
一、SVG 简介及基础语法 1. SVG 简介 SVG(Scalable Vector Graphics)是一种基于 XML 的矢量图形格式,用于在网页上显示二维图形。SVG 图形可以无限缩放而不会失真,非常适合用于图标、图表和复杂图形。SVG 文件是文本文件&#x…...

使用Allure作为测试报告生成器(Java+Selenium)
背景 JAVA项目中原先用Jenkinsseleniumselenium grid来日常测试UI并记录。 问题 当某一个testSuite失败时,当需要确认UI regression issue还是selenium test case自身的问题,需要去jenkins中查log,一般得到的是“Can not find element xxx…...

RocketMQ面试题合集
消费者获取消息是从Master Broker还是Slave Broker获取? Master Broker宕机,Slave Broker会自动切换为Master Broker吗? 这种Master-Slave模式不是彻底的高可用模式,他没法实现自动把Slave切换为Master。在RocketMQ 4.5之后&…...

Qt初识_对象树
个人主页:C忠实粉丝 欢迎 点赞👍 收藏✨ 留言✉ 加关注💓本文由 C忠实粉丝 原创 Qt初识_对象树 收录于专栏【Qt开发】 本专栏旨在分享学习Qt的一点学习笔记,欢迎大家在评论区交流讨论💌 目录 什么是对象树 为什么要引…...
axios的get和post请求,关于携带参数相关的讲解一下
在使用 Axios 发送 HTTP 请求时,GET 和 POST 请求携带参数的方式有所不同。以下是关于这两种请求方法携带参数的详细讲解: GET 请求携带参数 对于 GET 请求,参数通常附加在 URL 之后,以查询字符串的形式传递。 直接在 URL 中拼接…...

Vue前端开发-路由其他配置
在路由文件中,除了跳转配置外,还可以进行路径重定向配置,如果没有找到对应的地址,还可以实现404的配置,同时,如果某个页面需要权限登录,还可以进行路由守卫配置,接下来,分…...
框架建设实战7——定时任务组件
在金融系统中,或者其他对账系统里,往往离不开分布式定时任务。用来做查证或者重试处理。 分布式job目前一般有如下三种: 1.elastic job 当当出品,比较老牌。新公司用的应该不多了。 2.xxl-job 个人开源项目。便于二开;有简洁的后管配置界面,方便接入。 3.powerjob …...
mybatis 整合 ehcache
pom.xml <!-- ehcache依赖 --><dependency><groupId>org.mybatis.caches</groupId><artifactId>mybatis-ehcache</artifactId><version>1.1.0</version></dependency>ehcache.xml <?xml version"1.0" en…...

【PlantUML系列】用例图(三)
目录 一、组成部分 二、典型案例 一、组成部分 参与者(Actors):使用关键字 actor 后跟参与者的名称。用例(Use Cases):使用关键字 usecase 后跟用例的名称和编号(可选)。系统边界…...
发送请求时遇到了数据库完整性约束错误 1048 Column ‘platform‘ cannot be null
可以这样解决 在 Vue 2 中封装接口请求时,确保每次请求都包含 platform Header 参数的最佳实践是通过创建一个全局的 Axios 实例,并为这个实例设置默认的 Header。这样可以确保所有通过该实例发送的请求都会自动包含 platform 参数。此外,你…...

三菱FX3U模拟量产品的介绍
FX3u可编程控制器模拟量产品包括:特殊适配器、特殊功能模块的连接 1、连接在FX3U可编程控制器的左侧。 2、连接特殊适配器时,需要功能扩展板。 3、最多可以连接4台模拟量特殊适配器。 4、使用高速输入输出特殊适配器时,请将模拟量特殊适配器连…...
pdf转图片
目录 pdf2image库 PyMuPDF库 python-office库 pdfplumber库 pdf2image库 安装:pip install pdf2image 使用时会报错:pdf2image.exceptions.PDFInfoNotInstalledError: Unable to get page count. Is poppler installed and in PATH? 需要安装 po…...
RestClient
什么是RestClient RestClient 是 Elasticsearch 官方提供的 Java 低级 REST 客户端,它允许HTTP与Elasticsearch 集群通信,而无需处理 JSON 序列化/反序列化等底层细节。它是 Elasticsearch Java API 客户端的基础。 RestClient 主要特点 轻量级ÿ…...
web vue 项目 Docker化部署
Web 项目 Docker 化部署详细教程 目录 Web 项目 Docker 化部署概述Dockerfile 详解 构建阶段生产阶段 构建和运行 Docker 镜像 1. Web 项目 Docker 化部署概述 Docker 化部署的主要步骤分为以下几个阶段: 构建阶段(Build Stage):…...
C++:std::is_convertible
C++标志库中提供is_convertible,可以测试一种类型是否可以转换为另一只类型: template <class From, class To> struct is_convertible; 使用举例: #include <iostream> #include <string>using namespace std;struct A { }; struct B : A { };int main…...

PPT|230页| 制造集团企业供应链端到端的数字化解决方案:从需求到结算的全链路业务闭环构建
制造业采购供应链管理是企业运营的核心环节,供应链协同管理在供应链上下游企业之间建立紧密的合作关系,通过信息共享、资源整合、业务协同等方式,实现供应链的全面管理和优化,提高供应链的效率和透明度,降低供应链的成…...

vscode(仍待补充)
写于2025 6.9 主包将加入vscode这个更权威的圈子 vscode的基本使用 侧边栏 vscode还能连接ssh? debug时使用的launch文件 1.task.json {"tasks": [{"type": "cppbuild","label": "C/C: gcc.exe 生成活动文件"…...
【Go】3、Go语言进阶与依赖管理
前言 本系列文章参考自稀土掘金上的 【字节内部课】公开课,做自我学习总结整理。 Go语言并发编程 Go语言原生支持并发编程,它的核心机制是 Goroutine 协程、Channel 通道,并基于CSP(Communicating Sequential Processes࿰…...

视频字幕质量评估的大规模细粒度基准
大家读完觉得有帮助记得关注和点赞!!! 摘要 视频字幕在文本到视频生成任务中起着至关重要的作用,因为它们的质量直接影响所生成视频的语义连贯性和视觉保真度。尽管大型视觉-语言模型(VLMs)在字幕生成方面…...

ElasticSearch搜索引擎之倒排索引及其底层算法
文章目录 一、搜索引擎1、什么是搜索引擎?2、搜索引擎的分类3、常用的搜索引擎4、搜索引擎的特点二、倒排索引1、简介2、为什么倒排索引不用B+树1.创建时间长,文件大。2.其次,树深,IO次数可怕。3.索引可能会失效。4.精准度差。三. 倒排索引四、算法1、Term Index的算法2、 …...

(转)什么是DockerCompose?它有什么作用?
一、什么是DockerCompose? DockerCompose可以基于Compose文件帮我们快速的部署分布式应用,而无需手动一个个创建和运行容器。 Compose文件是一个文本文件,通过指令定义集群中的每个容器如何运行。 DockerCompose就是把DockerFile转换成指令去运行。 …...

mysql已经安装,但是通过rpm -q 没有找mysql相关的已安装包
文章目录 现象:mysql已经安装,但是通过rpm -q 没有找mysql相关的已安装包遇到 rpm 命令找不到已经安装的 MySQL 包时,可能是因为以下几个原因:1.MySQL 不是通过 RPM 包安装的2.RPM 数据库损坏3.使用了不同的包名或路径4.使用其他包…...