1. 程式人生 > >dljd_013_使用PreparedStatement避免SQL注入攻擊

dljd_013_使用PreparedStatement避免SQL注入攻擊

一、使用PreparedStatement來避免SQL注入攻擊示例

  這裡我只提供原始碼、測試類及結果截圖資訊、建庫/表的語句詳見上一集

package edu.aeon.logon;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.HashMap;
import java.util.Map;
import java.util.Scanner;

import edu.aeon.aeonutils.AeonJdbcUtils; /** * [說明]:實現使用者登入、並且演示sql注入攻擊 造成sql注入攻擊的原因 * 1.and和or的優先順序(and(可以理解為並且)優先與or(可以理解為或者))其實是構造or的條件來無視and條件 * 2.sql語句的拼接 * 如何解決sql注入攻擊? 資料庫and 和 or的優先順序天生的、我們無法改變 唯一解決思路: * 我們用預編譯的PreparedStatement來執行sql語句、這種方式不會去拼接sql語句的 * @author aeon * */ public
class UserLogon { /** * 封裝鍵盤輸入 * * @return */ public static Map<String, String> ReadBoard() { /** * 鍵盤掃描器:掃描鍵盤輸入的內容 */ Scanner scanner = new Scanner(System.in); System.out.println("請輸入使用者名稱:"); String username
= scanner.nextLine();// 以\n作為一行的標識來讀取一行 System.out.println("請輸入密碼:"); String password = scanner.nextLine(); Map<String, String> userMap = new HashMap<String, String>(); // 將鍵盤輸入的內容封裝到map集合中、並且返回給呼叫者 userMap.put("username", username); userMap.put("password", password); return userMap; } /** * 使用者登入具體實現 * * @return 登入成功標誌 true則登入成功、否則失敗! */ public static boolean userLogon() { boolean flag = false; Connection connection = null; PreparedStatement preparedStatement = null; ResultSet resultSet = null; try { // 連線資料庫 connection = AeonJdbcUtils.getMySqlConnection(); // 獲取到使用者輸入的資料 Map<String, String> userMap = ReadBoard(); // 登入sql 這裡sql語句要設定的內容、不管什麼型別,統統用?佔位符 String logonSql = "select * from user where username=? and userpw =?"; // 將sql語句預編譯到PreparedStatement物件當中 preparedStatement = connection.prepareStatement(logonSql); preparedStatement.setString(1, userMap.get("username")); preparedStatement.setString(2, userMap.get("password")); System.out.println(logonSql); // 因為sql語句已經被編譯到PreparedStatement物件中了,所以此處執行再也不需要sql語句 resultSet = preparedStatement.executeQuery(); if (resultSet.next()) { flag = true; } } catch (SQLException e) { e.printStackTrace(); } catch (ClassNotFoundException e) { e.printStackTrace(); } finally { AeonJdbcUtils.closeDB(resultSet, preparedStatement, connection); } return flag; } /** * 使用者登入測試 * * @param args */ public static void main(String[] args) { System.out.println(userLogon() ? "使用者登入成功!" : "使用者登入失敗!"); } }

  執行結果截圖(我們輸入錯誤的使用者名稱和密碼):

  

執行結果截圖(我們輸入正確的使用者名稱和相應密碼):

  

  執行結果截圖(再構造sql注入攻擊):

  

這樣我們通過預編譯的PreparedStatement執行sql語句來避免了sql注入的攻擊。