[Js-JDBC]SQL註入及解決,Statement與PreparedStatement
阿新 • • 發佈:2018-03-09
接收 現象 dsta ets 字符 如何 sel 單引號 con
SQL註入的含義
用戶在輸入信息中有SQL關鍵字並且參與SQL語句的編譯,導致SQL語句含義扭曲,這種現象被稱為SQL註入
例如:
1 // 在登錄驗證的時候使用如下語句 2 String sql =
"select * from tb_user where username = ‘"+username+"‘ and userpwd = ‘+pwd+‘";
而用戶在密碼處輸入:asd‘ or ‘a‘=‘a
則會導致
select * from tb_user where username = ‘admin‘ and userpwd = ‘asd‘ or ‘a‘=‘a‘;
顯而易見以上SQL語句條件永遠為真
根本原因:先拼接SQL語句字符串,然後再進行比那一,這個時候用戶提供的信息中含有SQL關鍵字,並參與了這次編譯,扭曲了原意
如何防止SQL註入
先定義SQL語句框架,對SQl語句進行預先編譯,只編譯一次,然後再去接收用戶提供的信息,用戶提供的信息中即使含有SQL語句的關鍵字,這些關鍵字不參與這次SQL語句的編譯,從而起不到作用,采用這種方式可以解決SQL註入問題
使用 PreparedStatement 代替 Statement 預編譯SQL語句,然後再傳入參數
註意:
有的系統是需要SQL註入的,比如 select * from where,這就需要使用 Statement
有的系統是要防止SQL註入的,比如登錄系統,所以使用 PreparedStatement
PreparedStatement 與 Statement 對比
- PreparedStatement 防止 SQL 註入 ,執行效率高
- SQL 語句對於 Statement 來說是:編譯一次執行一次;SQL 語句對於 PreparedStatement 是編譯一次執行 N 次
- PreparedStatement 是類型安全的,編譯期檢查傳入參數類型
註意:
使用 PreparedStatement 時 SQL 語句中的”?“不能寫在單引號中,否則無法識別,如下的句子是錯誤的
1 String sql = "select ename from emp where ename like ‘%?%‘";2 PreparedStatement ps = conn.prepareStatement(sql); 3 ps.setString(1, "0");
正確的應該為:
1 String sql = "select ename from emp where ename like ?"; 2 PreparedStatement ps = conn.prepareStatement(sql); 3 ps.setString(1, "%0%");
則會導致
[Js-JDBC]SQL註入及解決,Statement與PreparedStatement