mybatis SQL注入

2021-08-09 07:13:21 字數 2021 閱讀 9703

sql注入,大家都不陌生,是一種常見的攻擊方式。攻擊者在介面的表單資訊或url上輸入一些奇怪的sql片段(例如「or 『1』=』1』」這樣的語句),有可能入侵引數檢驗不足的應用程式。所以,在我們的應用中需要做一些工作,來防備這樣的攻擊方式。在一些安全性要求很高的應用中(比如銀行軟體),經常使用將sql語句全部替換為儲存過程這樣的方式,來防止sql注入。這當然是一種很安全的方式,但我們平時開發中,可能不需要這種死板的方式。

mybatis框架作為一款半自動化的持久層框架,其sql語句都要我們自己手動編寫,這個時候當然需要防止sql注入。其實,mybatis的sql是乙個具有「輸入+輸出」的功能,類似於函式的結構,如下:

select id,title,author,content

from blog

where id=#

這裡,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注入呢?當然不是,請看下面的**:

select id,title,author,content

from blog

where id=$

仔細觀察,內聯引數的格式由「#」變為了「$」。如果我們給引數「id」賦值為「3」,將sql列印出來是這樣的:

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

(上面的對比示例是我自己新增的,為了與前面的示例形成鮮明的對比。)

select id,title,author,content

from blog

order by $

仔細觀察,內聯引數的格式由「#」變為了「$」。如果我們給引數「orderparam」賦值為「id」,將sql列印出來是這樣的:

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

顯然,這樣是無法阻止sql注入的。在mybatis中,「xx

x」這樣

格式的參

數會直接

參與sq

l編譯,

從而不能

避免注入

攻擊。但

涉及到動

態表名和

列名時,

只能使用

「 」這樣的引數格式。所以,這樣的引數需要我們在**中手工進行處理來防止注入。

【結論】在編寫mybatis的對映語句時,盡量採用「#」這樣的格式。若不得不使用「$」這樣的引數,要手工地做好過濾工作,來防止sql注入攻擊。

${}:是輸出變數的值

簡單說,#{}是經過預編譯的,是安全的;${}是未經過預編譯的,僅僅是取變數的值,是非安全的,存在sql注入。

如果我們order by語句後用了${},那麼不做任何處理的時候是存在sql注入危險的。你說怎麼防止,那我只能悲慘的告訴你,你得手動處理過濾一下輸入的內容。如判斷一下輸入的引數的長度是否正常(注入語句一般很長),更精確的過濾則可以查詢一下輸入的引數是否在預期的引數集合中。

MyBatis SQL注入

使用mybatis的程式或系統,只要使用 傳遞的引數,就不會存在sql注入漏洞,因為它使用的是和jdbc的preparestatemnt物件,使用的預編譯傳遞引數,將轉義交給了資料庫,不會出現sql注入的問題。但如果使用不當,例如使用 來傳遞拼接引數就會有sql注入的問題。正確的用法 1 正確使用 ...

Mybatis SQL對映檔案

insert into tb employee last name,email,gender values update tb employee set last name email gender where id delete from tb employee where id select i...

手寫Mybatis SQL註解

資料庫中有user表 查詢 動態 invoke public object invoke object proxy,method method,object args throws throwable bxcselect select method.getdeclaredannotation bxc...