1. 程式人生 > >MySQL之使用預處理物件PreparedStatement防止注入攻擊

MySQL之使用預處理物件PreparedStatement防止注入攻擊

防止注入攻擊核心思想

通過預處理物件PreparedStatement,對SQL語句中引數列表進行指定傳參,防止使用者在SQL語句結尾上新增額外的SQL語句

SQL語句中引數列表

每條SQL語句中的引數全部採用問號佔位符

String sql = "insert into sort(sid,sname) values(?,?)";
PreparedStatement預處理物件程式碼:
PreparedStatement psmt = conn.prepareStatement(sql);

實際引數傳遞

將指定引數設定為給定Java的xx值。在將此值傳送到資料庫時,驅動程式將它轉換成一個 SQL Xxx型別值
	void setXxx(int index, Xxx xx);
把SQL語句中第2個位置的佔位符? 替換成實際引數 "mark"
        setString(2, "mark") 

案例

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.Scanner;


public class JDBCAntiAttack {
	private static Scanner sc;
	public static void main(String[] args) {
		/*
		 * 獲取使用者輸入的使用者名稱和密碼
		 */
		sc = new Scanner(System.in);
		System.out.println("請輸入使用者名稱:");
		String name = sc.next();
		System.out.println("請輸入密碼:");
		String pass = sc.next();
		
		/*
		 * 連線資料庫進行注入攻擊
		 */
		try {
			// 註冊資料庫
			Class.forName("com.mysql.jdbc.Driver");
		} catch (ClassNotFoundException e) {
			e.printStackTrace();
		}
		String url = "jdbc:mysql://localhost:3306/mybase";
		String username = "root";
		String password = "root";
		Connection conn = null;
		PreparedStatement pst = null;
		ResultSet rs = null;
		try {
			// 獲取連線
			conn = DriverManager.getConnection(url, username, password);
			//sql語句,執行驗證查詢
			String sql = "SELECT * FROM USER WHERE uname=? AND upassword=?";
			//預處理
			pst = conn.prepareStatement(sql);
			pst.setObject(1, name);
			pst.setObject(2, pass);
			System.out.println(sql);
			//執行sql語句
			rs = pst.executeQuery();
			if(rs.next()){
				System.out.println("使用者名稱和密碼驗證通過!");
			}
			else {
				System.out.println("使用者名稱和密碼驗證不通過!");
			}
		} catch (SQLException e) {
			e.printStackTrace();
		}finally{
			try {
				rs.close();
				pst.close();
				conn.close();
			} catch (SQLException e) {
				e.printStackTrace();
			}
		}
	}
}

測試結果