1. 程式人生 > >JDBC預處理物件PreprareStatement,預防SQL注入問題,提高安全性

JDBC預處理物件PreprareStatement,預防SQL注入問題,提高安全性

PreparedStatement介面是Statement的子介面,它直接繼承並重載了Statement的方法。
PreprareStatement預處理物件為什麼能預防SQL注入提高安全性呢?

因為SQL語句在程式執行前已經進行了預編譯,在程式執行時第一次操作資料庫之前,SQL語句已經被資料庫分析,編譯和優化,對應的執行計劃也會快取下來並允許資料庫以引數化的形式進行查詢,當執行時動態地把引數傳給PreprareStatement時,即使引數裡有敏感字元如 or '1=1’也資料庫會作為一個引數一個欄位的屬性值來處理而不會作為一個SQL指令,如此,就起到了SQL注入的作用了!

JDBC用預處理物件操作資料例項:

以delete刪除為例

	/**
     * 預處理物件PreparedStatement
     *
     * 提高執行速度尤其是多次操作資料庫的情況;預防SQL注入
     */
 		 void delete() {
        // TODO Auto-generated method stub
        String url = "jdbc:mysql://192.168.1.45:3306/employ";
        String uerName = "root";
        String password = "[email protected]
"; // 1.註冊驅動 try { Class.forName("com.mysql.jdbc.Driver"); } catch (ClassNotFoundException e) { // TODO Auto-generated catch block e.printStackTrace(); } Connection conn = null; PreparedStatement pstmt = null; try { // 2.獲得連線物件 conn = DriverManager.getConnection(url, uerName, password); // 3.預定義SQL語句 String sql = "DELETE FROM emp WHERE emp_no=?"; // 4.獲得預處理物件 pstmt = conn.prepareStatement(sql); // 5.設定引數值 pstmt.setInt(1, 99); // 6.執行更新SQL pstmt.executeUpdate(); } catch (SQLException e) { e.printStackTrace(); } finally { // 7.釋放資源 try { if (pstmt != null) { pstmt.close(); pstmt = null; } if (conn != null) { conn.close(); conn = null; } } catch (SQLException e) { e.printStackTrace(); } } }

PreprareStatement物件還支援批量處理addBatch,excuteBatch。

SQL注入攻擊指的是通過構建特殊的輸入作為引數傳入Web應用程式,而這些輸入大都是SQL語法裡的一些組合,通過執行SQL語句進而執行攻擊者所要的操作,其主要原因是程式沒有細緻地過濾使用者輸入的資料,致使非法資料侵入系統

SQL注入防範:

  1. 使用引數化的過濾性語句
    • 要防禦SQL注入,使用者的輸入就絕對不能直接被嵌入到SQL語句中。
  2. 輸入驗證
    • 檢查使用者輸入的合法性,確信輸入的內容只包含合法的資料。資料檢查應當在客戶端和伺服器端都執行。
  3. 加密處理
    • 將使用者登入名稱、密碼等資料加密儲存。加密使用者輸入的資料,然後再將它與資料庫中儲存的資料比較——這相當於對使用者輸入的資料進行了“消毒”處理,使用者輸入的資料不再對資料庫有任何特殊的意義,從而也就防止了攻擊者注入SQL命令。
  4. 儲存過程來執行所有的查詢
    • SQL引數的傳遞方式將防止攻擊者利用單引號和連字元實施攻擊。此外,它還使得資料庫許可權可以限制到只允許特定的儲存過程執行,所有的使用者輸入必須遵從被呼叫的儲存過程的安全上下文,這樣就很難再發生注入式攻擊了。