一区二区三区在线-一区二区三区亚洲视频-一区二区三区亚洲-一区二区三区午夜-一区二区三区四区在线视频-一区二区三区四区在线免费观看

服務器之家:專注于服務器技術及軟件下載分享
分類導航

PHP教程|ASP.NET教程|Java教程|ASP教程|編程技術|正則表達式|C/C++|IOS|C#|Swift|Android|VB|R語言|JavaScript|易語言|vb.net|

服務器之家 - 編程語言 - Java教程 - mybatis防止SQL注入的方法實例詳解

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

2021-04-24 11:15bwh0520 Java教程

SQL注入是一種很簡單的攻擊手段,但直到今天仍然十分常見。那么mybatis是如何防止SQL注入的呢?下面腳本之家小編給大家帶來了實例代碼,需要的朋友參考下吧

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

假設數據庫中存在這樣的表:

?
1
2
3
4
table user(
id varchar(20) primary key ,
name varchar(20) ,
age varchar(20) );

然后使用jdbc操作表:

?
1
2
3
4
5
6
7
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();
 ......
}

上面的代碼經常被一些開發人員使用。想象這樣的情況,當傳入的userid參數為"3;drop table user;"時,執行的sql語句如下:

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

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

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

?
1
2
3
4
5
6
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注入了呢?因為使用了預編譯語句,預編譯語句在執行時會把"select name from user where id= ?"語句事先編譯好,這樣當執行時僅僅需要用傳入的參數替換掉?占位符即可。而對于第一種不符合規范的情況,程序會先生成sql語句,然后帶著用戶傳入的內容去編譯,這恰恰是問題所在。

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

?
1
2
3
4
5
6
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);

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

?
1
2
3
4
5
6
7
8
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參數,用戶檢查到包含分號就提示錯誤。

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

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

?
1
2
3
<select id="getnamebyuserid" resulttype="string">
 select name from user where id = #{userid}
</select>

對應的java文件為:

?
1
2
3
public interface usermapper{
 string getnamebyuserid(@param("userid") string userid);
}

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

?
1
select name from user where id = ?

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

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

如果將上面的語句改成:

?
1
2
3
<select id="getnamebyuserid" resulttype="string">
 select name from user where id = ${userid}
</select>

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

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

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

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

總結

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

原文鏈接:https://blog.csdn.net/bwh0520/article/details/80102040

延伸 · 閱讀

精彩推薦
主站蜘蛛池模板: 私人影院在线免费观看 | 美女撒尿毛片免费看 | 久久精品国产视频澳门 | 秋霞717理论片在线观看 | 91亚洲视频在线观看 | 日本免费精品 | 日韩一区二区三区免费 | chinese老太grandma| 亚洲国产果果在线播放在线 | 人禽l交免费视频观看+视频 | 亚洲欧美日韩另类在线一 | coolgay男男gayxxx| 精品一二三区久久AAA片 | 日韩在线中文字幕 | 污污免费 | 国产精品亚欧美一区二区三区 | 亚洲女同在线观看 | 黑人k8经典| 无码AV毛片色欲欧洲美洲 | 4399h漫画 | 亚洲福利一区二区三区 | 亚洲va天堂va国产va久久 | 男女性潮高片无遮挡禁18 | 亚洲黄色图| 国产90后美女露脸在线观看 | 亚洲人成伊人成综合网久久 | 欧美香蕉人人人人人人爱 | 国产日产精品久久久久快鸭 | 久久精品一区二区三区资源网 | 久久受www免费人成_看片中文 | 色哟哟哟在线精品观看视频 | 亚洲国产日韩欧美在线vip1区 | 特级一级全黄毛片免费 | 大香焦在线 | 成年人免费在线看 | 九九久久精品 | 亚洲高清无码在线 视频 | 亚洲福利一区二区三区 | 亚洲欧美专区精品久久 | 色综合久久中文字幕 | 国产精品自拍一区 |