Mybatis 防止SQL注入筆記

#{xxx},使用的是PreparedStatement,會有類型轉換,因此比較安全;html

${xxx},使用字符串拼接,能夠SQL注入;sql

like查詢不當心會有漏洞,正確寫法以下:數據庫

Mysql: select * from t_user where name like concat('%', #{name}, '%')      安全

Oracle: select * from t_user where name like '%' || #{name} || '%'      mybatis

SQLServer: select * from t_user where name like '%' + #{name} + '%'框架

mybatis如何防止sql注入

sql注入你們都不陌生,是一種常見的攻擊方式,攻擊者在界面的表單信息或url上輸入一些奇怪的sql片斷,例如「or ‘1’=’1’」這樣的語句,有可能入侵參數校驗不足的應用程序。因此在咱們的應用中須要作一些工做,來防備這樣的攻擊方式。在一些安全性很高的應用中,好比銀行軟件,常常使用將sql語句所有替換爲存儲過程這樣的方式,來防止sql注入,這固然是一種很安全的方式,但咱們平時開發中,可能不須要這種死板的方式。函數

mybatis框架做爲一款半自動化的持久層框架,其sql語句都要咱們本身來手動編寫,這個時候固然須要防止sql注入。其實Mybatis的sql是一個具備「輸入+輸出」功能,相似於函數的結構,以下:url

1spa

2code

3

4

<select id=「getBlogById「 resultType=「Blog「 parameterType=」int」><br>

       select id,title,author,content from blog where id=#{id}

 

</select>

這裏,parameterType標示了輸入的參數類型,resultType標示了輸出的參數類型。迴應上文,若是咱們想防止sql注入,理所固然地要在輸入參數上下功夫。上面代碼中高亮部分即輸入參數在sql中拼接的部分,傳入參數後,打印出執行的sql語句,會看到sql是這樣的:

select id,title,author,content from blog where id = ?

無論輸入什麼參數,打印出的sql都是這樣的。這是由於mybatis啓用了預編譯功能,在sql執行前,會先將上面的sql發送給數據庫進行編譯,執行時,直接使用編譯好的sql,替換佔位符「?」就能夠了。由於sql注入只能對編譯過程起做用,因此這樣的方式就很好地避免了sql注入的問題。

mybatis是如何作到sql預編譯的呢?其實在框架底層,是jdbc中的PreparedStatement類在起做用,PreparedStatement是咱們很熟悉的Statement的子類,它的對象包含了編譯好的sql語句。這種「準備好」的方式不只能提升安全性,並且在屢次執行一個sql時,可以提升效率,緣由是sql已編譯好,再次執行時無需再編譯。

話說回來,是否咱們使用mybatis就必定能夠防止sql注入呢?固然不是,請看下面的代碼: 

1

2

3

4

5

<select id=「orderBlog「 resultType=「Blog「 parameterType=」map」>

 

       select id,title,author,content from blog order by ${orderParam}

 

</select>

仔細觀察,內聯參數的格式由「#{xxx}」變爲了${xxx}。若是咱們給參數「orderParam」賦值爲」id」,將sql打印出來,是這樣的:

select id,title,author,content from blog order by id

顯然,這樣是沒法阻止sql注入的。在mybatis中,」${xxx}」這樣格式的參數會直接參與sql編譯,從而不能避免注入攻擊。但涉及到動態表名和列名時,只能使用「${xxx}」這樣的參數格式,因此,這樣的參數須要咱們在代碼中手工進行處理來防止注入。

結論:在編寫mybatis的映射語句時,儘可能採用「#{xxx}」這樣的格式。若不得不使用「${xxx}」這樣的參數,要手工地作好過濾工做,來防止sql注入攻擊。

抄襲自:

http://blog.sina.com.cn/s/blog_667ac0360102vl85.html

http://www.cnblogs.com/sunada2005/p/4739312.html

相關文章
相關標籤/搜索