一、SQL注入
SQL注入是一種比較常見的網路攻擊方式,一些惡意人員在需要使用者輸入的地方,惡意輸入SQL語句的片段,通過SQL語句,實作無賬号登入,甚至篡改資料庫。
二、SQL注入執行個體
登入場景:
在一個登入界面,要求使用者輸入賬号和密碼。
我們的代碼中會有如下SQL語句:
情形1:(免賬号登入)
賬号:' or 1=1-- (--後面有一個空格)
密碼:
當我們輸入了這個賬号和密碼,那麼SQL語句就變成:
String sql="select * from user where account='' or 1=1 -- ' and password=''";

這個查詢條件就變成account=‘’ 或者1=1,這個條件是恒成立的。
後面的-- ,就是注釋。
這樣就可以實作免賬号登入。
情形2:(删除資料庫)
賬号:';drop database test;-- (--後面有一個空格)
密碼:
當我們輸入了這個賬号和密碼,那麼SQL語句就變成:
String sql="select * from user where account='';drop database test;-- ' and password=''";
這個查詢條件就變成account=‘’ 或者1=1,這個條件是恒成立的。
後面的-- ,就是注釋。
這樣就能删除資料庫。
三、防止SQL注入方法
使用PreparedStatement可以防止SQL注入。sql語句中的參數需要用?代替。PreparedStatement對sql預編譯後,然後調用setXX()方法設定sql語句中的參數。這樣再傳入特殊值,也不會出現sql注入的問題了。
四、登入項目
1、使用者表
使用者的賬号資訊:
create table user(
id int primary key auto_increment,
account varchar(20),
password varchar(20),
nickname varchar(20)
);
insert into user(account,password,nickname) values('Jack','123456','傑克');
insert into user(account,password,nickname) values('Mary','888888','瑪麗');
select*from user;
2、項目結構
建立一個javaweb項目。Login類實作登入功能,用Junit進行單元測試,建立LoginTest類實作登入測試功能。
3、登入實作
Login.java
package net.jdbc.test;
import java.math.BigDecimal;
import java.sql.*;
public class Login {
//資料庫url、使用者名和密碼
static final String DB_URL="jdbc:mysql://localhost:3306/test?";
static final String USER="root";
static final String PASS="root123";
public static void login(String account,String password) {
try {
//1、注冊JDBC驅動
Class.forName("com.mysql.jdbc.Driver");
//2、擷取資料庫連接配接
Connection connection = DriverManager.getConnection(DB_URL, USER, PASS);
//3、操作資料庫
String sql="select * from user where account=? and password=?";
//擷取操作資料庫的對象
//用PreparedStatement可以預防SQL注入
PreparedStatement preparedStatement = connection.prepareStatement(sql);
preparedStatement.setString(1,account);//設定參數
preparedStatement.setString(2,password);
ResultSet resultSet = preparedStatement.executeQuery();//執行查詢sql,擷取結果集
if (resultSet.next()){ //周遊結果集,取出資料
String name = resultSet.getString("nickname");
//輸出資料
System.out.println(name+"登入成功");
}else{
System.out.println("使用者登入失敗......");
}
//4、關閉結果集、資料庫操作對象、資料庫連接配接
resultSet.close();
preparedStatement.close();
connection.close();
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch(SQLException e){
e.printStackTrace();
} catch(Exception e){
e.printStackTrace();
}
}
}
4、登入測試
LoginTest.java
package net.jdbc.test;
import org.junit.Test;
import static org.junit.Assert.*;
public class LoginTest {
@Test
public void login() {
Login.login("' or 1=1-- ","");//SQL注入測試
Login.login("Jack","123");//正确賬号,錯誤密碼
Login.login("Jack","123456");
Login.login("Mary","888888");
}
}
運作結果: