关于Mybatis造成的Sql注入
2 分钟
前言
在之前课程设计的项目上进行了一些测试,发现存在sql注入,于是提取出来总结一下原因。
一、搭建
- 数据库如下:
- pom.xml
<?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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.7.9</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.example</groupId>
<artifactId>Sqldemo</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>Sqldemo</name>
<description>Sqldemo</description>
<properties>
<java.version>1.8</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-jdbc</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>2.3.0</version>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid-spring-boot-starter</artifactId>
<version>1.1.17</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<scope>runtime</scope>
<optional>true</optional>
</dependency>
<dependency>
<groupId>com.mysql</groupId>
<artifactId>mysql-connector-j</artifactId>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
二、使用步骤
1.引入库
代码如下(示例):
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns
import warnings
warnings.filterwarnings('ignore')
import ssl
ssl._create_default_https_context = ssl._create_unverified_context
- User类
package com.example.sqldemo.Bean;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.io.Serializable;
@Data
@AllArgsConstructor
@NoArgsConstructor
public class User implements Serializable {
private Integer id;
private String name;
private String phone;
private String username;
private String password;
private String email;
private Integer state;
}
- Mapper类
package com.example.sqldemo.mapper;
import com.example.sqldemo.Bean.User;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
import org.apache.ibatis.annotations.Select;
import org.springframework.core.annotation.Order;
import java.util.List;
@Mapper
public interface UserMapper {
@Select("select *from user where username=#{username}")
User findByUserName(String username);
@Select("select *from user where username='${username}'")
List<User> findByNameVuln(String username);
@Select("select *from user where username like concat('%',#{username},'%')")
List<User> Like(String username);
@Select("select *from user where username like '%${username}%' ")
List<User> Vuln01(String username);
}
- Controller层
package com.example.sqldemo.controller;
import com.example.sqldemo.Bean.User;
import com.example.sqldemo.mapper.UserMapper;
import org.apache.catalina.security.SecurityUtil;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse;
import java.security.Security;
import java.util.List;
@RestController
public class test {
@Resource
UserMapper userMapper;
@GetMapping("/sqli")
public List<User> sql(@RequestParam(name="username") String username, HttpServletResponse response){
return userMapper.findByNameVuln(username);
}
@GetMapping("/findUser")
public User find(@RequestParam(name="username") String username,HttpServletResponse response){
return userMapper.findByUserName(username);
}
@GetMapping("/Like")
public List<User> order(@RequestParam(name="username") String username,HttpServletResponse response){
return userMapper.Like(username);
}
@GetMapping("/Vuln01")
public List<User> Vuln(@RequestParam(name="username") String username,HttpServletResponse response){
return userMapper.Vuln01(username);
}
}
- application.yaml
spring:
datasource:
driver-class-name: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://localhost:3306/teamwork?useUnicode=true&characterEncoding=UTF-8&useSSL=false&serverTimezone=Asia/Shanghai
username: root
password: root
type: com.alibaba.druid.pool.DruidDataSource
mybatis:
# config-location: classpath:mybatis/mybatis-config.xml #全局配置文件位置
mapper-locations: classpath:mybatis/mapper/*.xml #sql映射文件位置
configuration:
map-underscore-to-camel-case: true
log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
2.测试
- 对根据用户名查询用户测试
通过日志直接输出mybatis可以看到,在创建SqlSession进行JDBC的时候,使用#{}会先使用?占位,然后经过Preparement类的预编译拼接,而使用${}时,Mybatis会直接拼接进入语句,导致了注入,但是这里似乎只能进行盲注,进行union注入时因为返回结果的原因会出现报错。 - Like测试的结果也一样
总结
在进行Mybatis查询数据库时,能使用#{}尽量使用#{},当需要进行order by等语句,使用预编译可能受阻的时,需要使用sql过滤器对输入的值进行sql防护。
~ ~ The End ~ ~
分类标签:Web安全,Web安全
文章标题:关于Mybatis造成的Sql注入
文章链接:https://aiwin.fun/index.php/archives/3063/
最后编辑:2024 年 1 月 4 日 16:52 By Aiwin
许可协议: 署名-非商业性使用-相同方式共享 4.0 国际 (CC BY-NC-SA 4.0)
文章标题:关于Mybatis造成的Sql注入
文章链接:https://aiwin.fun/index.php/archives/3063/
最后编辑:2024 年 1 月 4 日 16:52 By Aiwin
许可协议: 署名-非商业性使用-相同方式共享 4.0 国际 (CC BY-NC-SA 4.0)