注入攻擊
注入攻擊是web安全領域中一種最爲常見的攻擊方式。注入攻擊的本質,就是把用戶輸入的數據當做代碼執行。這裏有兩個關鍵條件,第一是用戶能夠控制輸入,第二個就是原本程序要執行的代碼,將用戶輸入的數據進行了拼接,所以防禦的思想就是基於上述兩個條件。
PS:OWASP Top 10是針對開發人員和Web應用程序安全性的標準意識文檔。它代表了對Web應用程序最嚴重的安全風險的廣泛共識。注入攻擊(injection)排在第一位。
SQL注入攻擊(SQL injection)是目前網站安全以及服務器安全層面上是最具有攻擊性,危害性較高,被黑客利用最多的一個漏洞,基本上針對於網站代碼,包括JAVA JSP PHP ASP apache tomcat 語言開發的代碼都會存在sql注入漏洞。
SQL注入攻擊代碼案例
比如我們想通過用戶名查詢用戶信息:
但是當我們稍微改下傳參 結果就會查出所有的用戶信息
UserController
package com.xdarker.security.controller;
import com.xdarker.security.dto.UserDto;
import com.xdarker.security.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.web.bind.annotation.*;
import java.util.List;
/**
* @Created by XDarker
* @Description TODO
* @Date 2020/3/1 15:20
*/
@RestController
@RequestMapping("/users")
public class UserController {
@Autowired
private JdbcTemplate jdbcTemplate;
@GetMapping
public List query(String name) {
String sql = "select * from user where name = '" + name + "'";
List list = jdbcTemplate.queryForList(sql);
return list;
// return userService.query(name);
}
}
sql:"select * from user where name = '" + name + "'" 分析SQL語句: 條件後面name=”or 1=1 用戶名等於 ” 或1=1 那麼這個條件一定會成功;
mybatis 解決 SQL 注入問題
我們使用 mybatis 編寫 SQL 語句時,難免會使用模糊查詢的方法,mybatis 提供了兩種方式 #{}
和 ${}
。
#{value}
在預處理時,會把參數部分用一個佔位符 ? 替代,其中 value 表示接受輸入參數的名稱。能有效解決 SQL 注入問題${}
表示使用拼接字符串,將接受到參數的內容不加任何修飾符拼接在 SQL 中,使用${}
拼接 sql,將引起 SQL 注入問題。
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>com.xdarker.security</groupId>
<artifactId>is-user-api</artifactId>
<version>1.0-SNAPSHOT</version>
<packaging>war</packaging>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-jdbc</artifactId>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
<version>28.2-jre</version>
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId>
</dependency>
</dependencies>
<!-- 版本管理-->
<dependencyManagement>
<dependencies>
<dependency>
<!-- Import dependency management from Spring Boot -->
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-dependencies</artifactId>
<version>2.2.5.RELEASE</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
</project>
用戶對象User
package com.xdarker.security.entity;
import lombok.Data;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
/**
* @Created by XDarker
* @Description TODO
* @Date 2020/3/1 15:15
*/
@Entity
@Data
public class User {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String name;
private String username;
private String password;
}