关于Mybatis造成的Sql注入

2 分钟

前言

在之前课程设计的项目上进行了一些测试,发现存在sql注入,于是提取出来总结一下原因。


一、搭建

  1. 数据库如下:
    file
  2. 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
  1. 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;
}
  1. 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);
}
  1. 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);
    }
}
  1. 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.测试

  1. 对根据用户名查询用户测试
    file
    file
    file
    file
    file
    file
    通过日志直接输出mybatis可以看到,在创建SqlSession进行JDBC的时候,使用#{}会先使用?占位,然后经过Preparement类的预编译拼接,而使用${}时,Mybatis会直接拼接进入语句,导致了注入,但是这里似乎只能进行盲注,进行union注入时因为返回结果的原因会出现报错。
  2. Like测试的结果也一样
    file
    file

总结

在进行Mybatis查询数据库时,能使用#{}尽量使用#{},当需要进行order by等语句,使用预编译可能受阻的时,需要使用sql过滤器对输入的值进行sql防护。

~  ~  The   End  ~  ~


 赏 
承蒙厚爱,倍感珍贵,我会继续努力哒!
logo图像
tips
文章二维码 分类标签: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)
(*) 3 + 6 =
快来做第一个评论的人吧~