mybatis是如何防止sql註入?
sql註入發生的時間,sql註入發生的階段在sql預編譯階段,當編譯完成的sql不會產生sql註入
采用jdbc操作數據時候
String sql = "update ft_proposal set id = "+id; PreparedStatement prepareStatement = conn.prepareStatement(sql); prepareStatement.executeUpdate();
preparedStatement 預編譯對象會對傳入sql進行預編譯,那麽當傳入id 字符串為 "update ft_proposal set id = 3;drop table ft_proposal;" 這種情況下就會導致sql註入刪除ft_proposal這張表。
如何防止sql註入,首先將要執行sql進行預編譯,然後在將占位符進行替換
String sql = "update ft_proposal set id = ?" PreparedStatement ps = conn.preparedStatement(sql); ps.setString(1,"2"); ps.executeUpdate();
處理使用預編譯語句之外,另一種實現方式可以采用存儲過程,存儲過程其實也是預編譯的,存儲過程是sql語句的集合,將所有預編譯的sql 語句編譯完成後,存儲在數據庫上,
由於存儲過程比較死板一般不采用這種方式進行處理。
二、mybatis是如何處理sql註入的?
假設mapper.xml文件中sql查詢語句為:
<select id="findById" resultType="String"> select name from user where id = #{userid}; </select>
對應的接口為:
public String findById(@param("userId")String userId);
當傳入的參數為3;drop table user; 當我們執行時可以看見打印的sql語句為:
select name from usre where id = ?;
不管輸入何種參數時,都可以防止sql註入,因為mybatis底層實現了預編譯,底層通過prepareStatement預編譯實現類對當前傳入的sql進行了預編譯,這樣就可以防止sql註入了。
如果將查詢語句改寫為:
<select id="findById" resultType = "String"> select name from user where id=${userid} </select>
當輸入參數為3;drop table user; 執行sql語句為
select name from user where id = 3;drop table user ;
mybatis沒有進行預編譯語句,它先進行了字符串拼接,然後進行了預編譯。這個過程就是sql註入生效的過程。
因此在編寫mybatis的映射語句時,盡量采用“#{xxx}”這樣的格式。若不得不使用“${xxx}”這樣的參數,要手工地做好過濾工作,來防止sql註入攻擊。
mybatis是如何防止sql註入?