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

dljd_013_使用PreparedStatement避免SQL註入攻擊

返回 flag 拼接 scan user bool 改變 tac mysq

一、使用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註入的攻擊。

dljd_013_使用PreparedStatement避免SQL註入攻擊