最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

mybatis防止SQL注入的方法實例詳解

 更新時間:2018年04月28日 09:36:48   作者:bwh0520  
SQL注入是一種很簡單的攻擊手段,但直到今天仍然十分常見。那么mybatis是如何防止SQL注入的呢?下面腳本之家小編給大家?guī)砹藢嵗a,需要的朋友參考下吧

SQL注入是一種很簡單的攻擊手段,但直到今天仍然十分常見。究其原因不外乎:No patch for stupid。為什么這么說,下面就以JAVA為例進行說明:

假設數(shù)據(jù)庫中存在這樣的表:

table user( 
id varchar(20) PRIMARY KEY , 
name varchar(20) , 
age varchar(20) ); 

然后使用JDBC操作表:

private String getNameByUserId(String userId) { 
 Connection conn = getConn();//獲得連接 
String sql = "select name from user where id=" + userId; 
 PreparedStatement pstmt = conn.prepareStatement(sql); 
 ResultSet rs=pstmt.executeUpdate(); 
 ...... 
} 

上面的代碼經(jīng)常被一些開發(fā)人員使用。想象這樣的情況,當傳入的userId參數(shù)為"3;drop table user;"時,執(zhí)行的sql語句如下:

select name from user where id=3; drop table user; 

數(shù)據(jù)庫在編譯執(zhí)行之后,刪除了user表。瞧,一個簡單的SQL注入攻擊生效了!之所以這樣,是因為上面的代碼沒有符合編程規(guī)范。

當我們按照規(guī)范編程時,SQL注入就不存在了。這也是避免SQL注入的第一種方式:預編譯語句,代碼如下:

 Connection conn = getConn();//獲得連接 
String sql = "select name from user where id= ?"; 
PreparedStatement pstmt = conn.prepareStatement(sql); 
pstmt.setString(1, userId); 
ResultSet rs=pstmt.executeUpdate(); 
.... 

為什么上面的代碼就不存在SQL注入了呢?因為使用了預編譯語句,預編譯語句在執(zhí)行時會把"select name from user where id= ?"語句事先編譯好,這樣當執(zhí)行時僅僅需要用傳入的參數(shù)替換掉?占位符即可。而對于第一種不符合規(guī)范的情況,程序會先生成sql語句,然后帶著用戶傳入的內容去編譯,這恰恰是問題所在。

除了使用預編譯語句之外,還有第二種避免SQL注入攻擊的方式:存儲過程。存儲過程(Stored Procedure)是一組完成特定功能的SQL語句集,經(jīng)編譯后存儲在數(shù)據(jù)庫中,用戶通過調用存儲過程并給定參數(shù)(如果該存儲過程帶有參數(shù))就可以執(zhí)行它,也可以避免SQL注入攻擊

 Connection conn = getConn(); 
stmt = conn.prepareCall("{call name_from_user(?,?)}"); 
stmt.setInt(1,2); 
stmt.registerOutParameter(2, Types.VARCHAR); 
stmt.execute(); 
String name= stmt.getString(2); 

上面的代碼中對應的存儲過程如下:

use user; 
delimiter // 
create procedure name_from_user(in user_id int,out user_name varchar(20)) 
begin 
 select name into user_name from user where id=user_id; 
end 
// 
delimiter ; 

當然用戶也可以在前端做字符檢查,這也是一種避免SQL注入的方式:比如對于上面的userId參數(shù),用戶檢查到包含分號就提示錯誤。

不過,從最根本的原因看,SQL注入攻擊之所以存在,是因為app在訪問數(shù)據(jù)庫時沒有使用最小權限。想來也是,大家好像一直都在使用root賬號訪問數(shù)據(jù)庫。

那么mybatis是如何避免sql注入攻擊的呢?還是以上面的表user為例:
假設mapper文件為:

<select id="getNameByUserId" resultType="String"> 
 SELECT name FROM user where id = #{userId} 
</select> 

對應的java文件為:

public interface UserMapper{ 
 String getNameByUserId(@Param("userId") String userId); 
}

可以看到輸入的參數(shù)是String類型的userId,當我們傳入userId="34;drop table user;"后,打印的語句是這樣的:

select name from user where id = ? 

不管輸入何種userID,他的sql語句都是這樣的。這就得益于mybatis在底層實現(xiàn)時使用預編譯語句。數(shù)據(jù)庫在執(zhí)行該語句時,直接使用預編譯的語句,然后用傳入的userId替換占位符?就去運行了。不存在先替換占位符?再進行編譯的過程,因此SQL注入也就沒有了生存的余地了。

那么mybatis是如何做到sql預編譯的呢?其實框架底層使用的正是PreparedStatement類。PreparedStaement類不但能夠避免SQL注入,因為已經(jīng)預編譯,當N次執(zhí)行同一條sql語句時,節(jié)約了(N-1)次的編譯時間,從而能夠提高效率。

如果將上面的語句改成:

<select id="getNameByUserId" resultType="String"> 
 SELECT name FROM user where id = ${userId} 
</select> 

當我們輸入userId="34;drop table user;"后,打印的語句是這樣的:

select name from user where id = 34;drop table user; 

此時,mybatis沒有使用預編譯語句,它會先進行字符串拼接再執(zhí)行編譯,這個過程正是SQL注入生效的過程。

因此在編寫mybatis的映射語句時,盡量采用“#{xxx}”這樣的格式。若不得不使用“${xxx}”這樣的參數(shù),要手工地做好過濾工作,來防止sql注入攻擊。

總結

以上所述是小編給大家介紹的mybatis防止SQL注入的方法實例詳解,希望對大家有所幫助,如果大家有任何疑問請給我留言,小編會及時回復大家的。在此也非常感謝大家對腳本之家網(wǎng)站的支持!

相關文章

  • IDEA中設置代碼自動提示為Alt+/的具體做法

    IDEA中設置代碼自動提示為Alt+/的具體做法

    很多公司都強制性要求使用Intellij?IDEA,其實Intellij?IDEA也確實很好用,但是一下子從Eclipse跳轉到Intellij?IDEA轉也是需要一段時間的,為了迎合之前的習慣,就需要在Intellij?IDEA中改變一些設置,如代碼自動生成,本文給大家分享設置方法,感興趣的朋友一起看看吧
    2023-01-01
  • idea安裝漢化插件的圖文教程

    idea安裝漢化插件的圖文教程

    本文主要介紹了idea安裝漢化插件的圖文教程,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2023-07-07
  • SpringBoot模擬實現(xiàn)流式輸出效果

    SpringBoot模擬實現(xiàn)流式輸出效果

    這篇文章主要為大家詳細介紹了如何使用SpringBoot模擬實現(xiàn)流式輸出效果,并在前端使用流式接收數(shù)據(jù)并打印,感興趣的小伙伴可以參考一下
    2025-03-03
  • EventBus與Spring Event區(qū)別詳解(EventBus 事件機制,Spring Event事件機制)

    EventBus與Spring Event區(qū)別詳解(EventBus 事件機制,Spring Event事件機制)

    這篇文章主要介紹了EventBus與Spring Event區(qū)別,需要的朋友可以參考下
    2020-02-02
  • MyBatis 自動更新時間的方法實現(xiàn)

    MyBatis 自動更新時間的方法實現(xiàn)

    本文主要介紹了MyBatis 自動更新時間的方法實現(xiàn),文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2024-06-06
  • Java程序生成exe可執(zhí)行文件詳細教程(圖文說明)

    Java程序生成exe可執(zhí)行文件詳細教程(圖文說明)

    這篇文章主要介紹了Java程序生成exe可執(zhí)行文件詳細教程,有需要的朋友可以參考一下
    2013-12-12
  • 一文帶你探究Spring中Bean的線程安全性問題

    一文帶你探究Spring中Bean的線程安全性問題

    很多人都想spring中的bean是線程安全的嗎?本文將帶你探究Spring中Bean的線程安全性問題,感興趣的同學可以參考閱讀下
    2023-05-05
  • Java調用Redis集群代碼及問題解決

    Java調用Redis集群代碼及問題解決

    這篇文章主要介紹了Java調用Redis集群代碼及問題解決,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友可以參考下
    2019-08-08
  • SpringBoot中的@PreAuthorize注解詳解

    SpringBoot中的@PreAuthorize注解詳解

    這篇文章主要介紹了SpringBoot中的@PreAuthorize注解詳解,@PreAuthorize注解會在方法執(zhí)行前進行權限驗證,支持Spring?EL表達式,它是基于方法注解的權限解決方案,需要的朋友可以參考下
    2023-09-09
  • java面試應用上線后Cpu使用率飆升如何排查

    java面試應用上線后Cpu使用率飆升如何排查

    這篇文章主要為大家介紹了java面試中應用上線后Cpu使用率飆升如何排查的方法示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪
    2022-07-07

最新評論

高邮市| 淳化县| 始兴县| 阳谷县| 高密市| 偃师市| 南充市| 株洲市| 定襄县| 申扎县| 霞浦县| 高邮市| 布拖县| 佳木斯市| 奉节县| 明光市| 竹北市| 永登县| 林芝县| 赤峰市| 长岭县| 项城市| 江口县| 肇庆市| 于田县| 门头沟区| 南雄市| 淅川县| 扬中市| 湖口县| 财经| 河北省| 宜兰市| 华宁县| 佛冈县| 新乡县| 合川市| 天峨县| 嘉鱼县| 油尖旺区| 甘南县|