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

實(shí)例講解MyBatis如何防止SQL注入

 更新時間:2021年12月03日 11:22:11   作者:義臻  
這篇文章通過實(shí)例代碼介紹MyBatis如何防止SQL注入,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧

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

假設(shè)數(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ā)人員使用。想象這樣的情況,當(dāng)傳入的userId參數(shù)為"3;drop table user;"時,執(zhí)行的sql語句如下:

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

數(shù)據(jù)庫在編譯執(zhí)行之后,刪除了user表。瞧,一個簡單的SQL注入攻擊生效了!之所以這樣,是因?yàn)樯厦娴拇a沒有符合編程規(guī)范。

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

               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注入了呢?因?yàn)槭褂昧祟A(yù)編譯語句,預(yù)編譯語句在執(zhí)行時會把"select name from user where id= ?"語句事先編譯好,這樣當(dāng)執(zhí)行時僅僅需要用傳入的參數(shù)替換掉?占位符即可。而對于第一種不符合規(guī)范的情況,程序會先生成sql語句,然后帶著用戶傳入的內(nèi)容去編譯,這恰恰是問題所在。

除了使用預(yù)編譯語句之外,還有第二種避免SQL注入攻擊的方式:存儲過程。存儲過程(Stored Procedure)是一組完成特定功能的SQL語句集,經(jīng)編譯后存儲在數(shù)據(jù)庫中,用戶通過調(diào)用存儲過程并給定參數(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); 

上面的代碼中對應(yīng)的存儲過程如下:

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 ;

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

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

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

假設(shè)mapper文件為:

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

對應(yīng)的java文件為:

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

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

select name from user where id = ?

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

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

如果將上面的語句改成:

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

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

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

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

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

以上所述是小編給大家介紹的MyBatis如何防止SQL注入,希望對大家有所幫助。在此也非常感謝大家對腳本之家網(wǎng)站的支持!

相關(guān)文章

  • 詳解Java的Hibernate框架中的搜索工具的運(yùn)用

    詳解Java的Hibernate框架中的搜索工具的運(yùn)用

    這篇文章主要介紹了詳解Java的Hibernate框架中的搜索工具的運(yùn)用,Hibernate是Java的SSH三大web開發(fā)框架之一,需要的朋友可以參考下
    2015-11-11
  • java Arrays類詳解及實(shí)例代碼

    java Arrays類詳解及實(shí)例代碼

    這篇文章主要介紹了java Arrays類詳解及實(shí)例代碼的相關(guān)資料,需要的朋友可以參考下
    2016-10-10
  • Spring Cloud Zuul的重試配置詳解

    Spring Cloud Zuul的重試配置詳解

    這篇文章主要介紹了Spring Cloud Zuul的重試配置詳解,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2018-04-04
  • Spring Data MongoDB 數(shù)據(jù)庫批量操作的方法

    Spring Data MongoDB 數(shù)據(jù)庫批量操作的方法

    在項(xiàng)目開發(fā)中經(jīng)常會批量插入數(shù)據(jù)和更新數(shù)據(jù)的操作,這篇文章主要介紹了Spring Data MongoDB 數(shù)據(jù)庫批量操作的方法,非常具有實(shí)用價值,需要的朋友可以參考下
    2018-11-11
  • Java中的@Async異步功能詳解

    Java中的@Async異步功能詳解

    這篇文章主要介紹了Java中的@Async異步功能詳解,@Async注解,可以實(shí)現(xiàn)異步處理的功能,它可以有返回值,或者直接在新線程時并行執(zhí)行一個任務(wù),對于異步來說,它的執(zhí)行是有條件的,你需要把異步代碼塊放在單獨(dú)的類里,需要的朋友可以參考下
    2023-11-11
  • Java數(shù)組(Array)最全匯總(上篇)

    Java數(shù)組(Array)最全匯總(上篇)

    這篇文章主要介紹了Java數(shù)組(Array)最全匯總(上篇),本文章內(nèi)容詳細(xì),通過案例可以更好的理解數(shù)組的相關(guān)知識,本模塊分為了三部分,本次為上篇,需要的朋友可以參考下
    2023-01-01
  • JAVA?從完整的文件路徑中分別截取文件名和文件路徑的實(shí)現(xiàn)

    JAVA?從完整的文件路徑中分別截取文件名和文件路徑的實(shí)現(xiàn)

    在Java編程中,經(jīng)常會遇到需要截取文件名的場景,本文主要介紹了JAVA?從完整的文件路徑中分別截取文件名和文件路徑的實(shí)現(xiàn),具有一定的參考價值,感興趣的可以了解一下
    2024-04-04
  • Spring Data JPA實(shí)現(xiàn)動態(tài)條件與范圍查詢實(shí)例代碼

    Spring Data JPA實(shí)現(xiàn)動態(tài)條件與范圍查詢實(shí)例代碼

    本篇文章主要介紹了Spring Data JPA實(shí)現(xiàn)動態(tài)條件與范圍查詢實(shí)例代碼,非常具有實(shí)用價值,需要的朋友可以參考下
    2017-06-06
  • SpringBoot讀取Resource下文件的4種方法

    SpringBoot讀取Resource下文件的4種方法

    這篇文章主要介紹了SpringBoot讀取Resource下文件的4種方法小結(jié),具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2021-07-07
  • 希爾排序的算法代碼

    希爾排序的算法代碼

    希爾排序也是一種插入排序方法,實(shí)際上是一種分組插入方法。
    2013-03-03

最新評論

宝鸡市| 历史| 北海市| 上饶市| 万安县| 达拉特旗| 莎车县| 天柱县| 安吉县| 绥江县| 东丰县| 郁南县| 进贤县| 康乐县| 栖霞市| 苍梧县| 昌都县| 凉山| 大冶市| 深水埗区| 襄汾县| 日照市| 浪卡子县| 曲周县| 南昌市| 聊城市| 团风县| 竹山县| 衡阳县| 上高县| 德兴市| 永泰县| 铜鼓县| 富裕县| 巴林右旗| 固阳县| 河西区| 永登县| 正宁县| 闻喜县| 青铜峡市|