JAVA安全—SpringBoot框架MyBatis注入Thymeleaf模板注入

news2024/12/13 1:37:31

前言

之前我们讲了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/user
        username: root
        password: 123456
        driver-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 {
    @Autowired
    private 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框架常见的安全问题,感觉有点强度了,哎。

最后,以上仅为个人的拙见,如何有不对的地方,欢迎各位师傅指正与补充,有兴趣的师傅可以一起交流学习。

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

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

相关文章

备忘录模式的理解和实践

引言 在软件开发中&#xff0c;我们经常会遇到需要保存对象状态并在某个时间点恢复到该状态的需求。这种需求类似于我们平时说的“后悔药”&#xff0c;即允许用户撤销之前的操作&#xff0c;恢复到某个之前的状态。备忘录模式&#xff08;Memento Pattern&#xff09;正是为了…

STL——string剖析

STL——string剖析 文章目录 STL——string剖析1. C语言中的字符串2. 标准库中string的使用2.1 构造函数2.2 string的容量操作resize和reserve 2.3 string的增删查改插入操作push_back&#xff1a;insert&#xff1a; 删除操作pop_back&#xff1a;erase 查找操作findfind_firs…

Ubuntu24.04配置STMTrack

项目地址&#xff1a;https://github.com/fzh0917/STMTrack 一、安装 CUDA 参考链接&#xff1a; Ubuntu24.04配置DINO-Tracker Ubuntu多CUDA版本安装及切换 由于之前在其他项目中已经安装了 CUDA12.1&#xff0c;这次需要安装另一个版本。 1. 查看安装版本 按照 requireme…

Android显示系统(08)- OpenGL ES - 图片拉伸

Android显示系统&#xff08;02&#xff09;- OpenGL ES - 概述 Android显示系统&#xff08;03&#xff09;- OpenGL ES - GLSurfaceView的使用 Android显示系统&#xff08;04&#xff09;- OpenGL ES - Shader绘制三角形 Android显示系统&#xff08;05&#xff09;- OpenGL…

【实现多网卡电脑的网络连接共享】

电脑A配备有两张网卡&#xff0c;分别命名为eth0和eth1&#xff08;对于拥有超过两张网卡的情况&#xff0c;解决方案相似&#xff09;。其中&#xff0c;eth0网卡能够连接到Internet&#xff0c;而eth1网卡则通过网线直接与另一台电脑B相连&#xff08;在实际应用中&#xff0…

聊聊在应用层面实现内网穿透功能是否可行

前言 最近接手了供方开发的网关项目&#xff0c;交接文档里面有个内网穿透的功能&#xff0c;一下子就吸引的我的目光。实现这个内网穿透的背景是业务部门有些业务是部署在公网&#xff0c;这些公网的业务想访问内网的业务&#xff0c;但因为公网和内网没打通&#xff0c;导致…

头歌 计算机操作系统 Linux之线程同步二

第1关&#xff1a;信号量 任务描述 在上一个实训中&#xff0c;我们学习了使用互斥锁来实现线程的同步&#xff0c;Linux系统中还提供了另一个类似互斥锁的线程不同操作&#xff0c;那就是信号量。 本关任务&#xff1a;学会使用信号量来实现线程间的同步与互斥。 相关知识 …

基于MinIO打造高可靠分布式“本地”文件系统

MinIO是一款高性能的对象存储服务&#xff0c;而S3协议是由亚马逊Web服务&#xff08;AWS&#xff09;制定的一种标准协议&#xff0c;用于云存储服务之间的数据交换。MinIO与S3协议的关系在于&#xff0c;MinIO实现了S3协议的接口&#xff0c;这意味着用户可以使用与AWS S3相同…

【MIT-OS6.S081作业1.3】Lab1-utilities primes

本文记录MIT-OS6.S081 Lab1 utilities 的primes函数的实现过程 文章目录 1. 作业要求primes (moderate)/(hard) 2. 实现过程2.1 代码实现 1. 作业要求 primes (moderate)/(hard) Write a concurrent version of prime sieve using pipes. This idea is due to Doug McIlroy, in…

Js如和返回数组中的指定列

一、需求 日常工作中需要返回数组中的指定列&#xff0c;例如Echarts 和 下拉框 选择 id&#xff0c;value 类似这种都需要在数组中提取指定列元素。 二、代码示例 const products [{ name: "商品1", price: 100, inventory: 50 },{ name: "商品2", pri…

C++的一些经典算法

以下是C的一些经典算法&#xff1a; 一、排序算法 冒泡排序&#xff08;Bubble Sort&#xff09; 原理&#xff1a; 它重复地走访过要排序的数列&#xff0c;一次比较两个元素&#xff0c;如果它们的顺序错误就把它们交换过来。走访数列的工作是重复地进行直到没有再需要交换…

35.1 thanos项目介绍和二进制部署

本节重点介绍 : 核心优点 无需维护存储&#xff0c;存储高可用&#xff1a; 利用廉价的公有云对象存储&#xff0c;高可用长时间存储&#xff0c;数据降采样&#xff1a;利用Compactor降采样完全适配原生prometheus查询接口&#xff1a;Query实现多级数据缓存配置 二进制部署 …

【PlantUML系列】状态图(六)

一、状态图的组成部分 状态&#xff1a;对象在其生命周期内可能处于的条件或情形&#xff0c;使用 state "State Name" as Statename 表示。初始状态&#xff1a;表示对象生命周期的开始&#xff0c;使用 [*] 表示。最终状态&#xff1a;表示对象生命周期的结束&…

Android 15(V)新功能适配,雕琢移动细节之美

Android 15&#xff0c;内部代号为Vanilla Ice Cream&#xff0c;是Android移动操作系统的最新主要版本&#xff0c;于2024年2月16日在开发者预览版1中发布。Android 15源代码于 2024年9月4日发布。Android 15稳定版于2024年10月15日发布。 以下是针对 Android 15&#xff08;…

【零成本抽象】基本概念与在C++中的实现

零成本抽象概念是由 Bjarne Stroustrup 提出的,他在 1994 年的著作中就有相关设想,2016 年其在 C++ 大会登台演讲时,明确阐述了 C++ 中的 “零成本抽象” 这一理念。 一、零成本抽象概念 Bjarne Stroustrup提出的零成本抽象概念,是指在编程中使用高级抽象机制时,不会产生…

android编译assets集成某文件太大更新导致git仓库变大

不知道大家有没有类似的困扰&#xff0c;你的工程assets文件过大&#xff0c;我曾经在某度车机地图团队工作过一段时间时候&#xff0c;每次发包会集成一个上百MB的文件。工作一段时间你的git仓库将会增加特别多。最后&#xff0c;你会发现你如果重新git clone这个仓库会非常大…

F5-TTS文本语音合成模型的使用和接口封装

F5-TTS文本语音生成模型 1. F5-TTS的简介 2024年10月8日&#xff0c;上海交通大学团队发布&#xff0c;F5-TTS (A Fairytaler that Fakes Fluent and Faithful Speech with Flow Matching) 是一款基于扩散Transformer和ConvNeXt V2的文本转语音 (TTS) 模型。F5-TTS旨在生成流…

克隆选择算法复现

克隆选择算法复现 基于克隆选择算法求解0 - 1背包问题的代码复现文档一、背景和意义&#xff08;一&#xff09;背景&#xff08;二&#xff09;意义 二、算法原理&#xff08;一&#xff09;克隆选择算法基础&#xff08;二&#xff09;受体编辑机制 三、算法流程&#xff08;…

Scala的隐式对象

Scala中&#xff0c;隐式对象&#xff08;implicit object&#xff09;是一种特殊的对象&#xff0c;它可以使得其成员&#xff08;如方法和值&#xff09;在特定的上下文中自动可用&#xff0c;而无需显式地传递它们。隐式对象通常与隐式参数和隐式转换一起使用&#xff0c;以…

观察者模式的理解和实践

引言 在软件开发中&#xff0c;设计模式是开发者们为了解决常见的设计问题而总结出来的一系列最佳实践。观察者模式&#xff08;Observer Pattern&#xff09;是其中一种非常经典且使用率极高的设计模式。它主要用于定义对象之间的一对多关系&#xff0c;使得当一个对象的状态发…