記一次sql注入實踐
今天開發程式碼的時候發現自己的sql全是拼接的,不是where a = ?的那種,細思恐極啊,於是進行了一場sql注入實踐。雖然失敗了,但是還是得出了一些寶貴的經驗。
首先從一個基礎的分頁查詢語句開始分析:
Select r.a,r.b from role r where r.name like ‘role%’ order by r.create_time desc liimit 0,10;
說明:使用者在介面輸入的是role,其他都是stringbuilder拼接的。
一開始嘗試使用如下輸入:’delete from x ‘
那sql語句變成如下形式:
Select r.a,r.b from role r where r.name like ‘’delete from x ’%’ order by r.create_time desc liimit 0,10;
看到的現象是前端沒有查詢到資料,給了彈框提示,但是分頁條顯示undefined.
後來從網上查到sql 的like 注入可以是下面的形式:
%' AND 1=1 AND '%'='
那sql語句則變成如下形式:
SELECT r.a,r.b FROM role r WHERE r.name LIKE '%' AND 1=1 AND '%'='%' ORDER BY r.create_time DESC liimit 0,10;
這樣的話一眼就看出來這是個正常的sql語句,並且可以被注入,是不是有點小兒科或者感到驚恐。放到資料庫裡執行應該是沒有問題的。
那怎麼才能更有威脅性呢,看如下sql語句:
SELECT r.a,r.b FROM role r WHERE r.name LIKE '%' AND 1=1 ;DELETE FROM rule WHERE 1=1 ; AND '%'='%' ORDER BY r.create_time DESC liimit 0,10;
那現在只要稍加修改就可以變成下面的形式:
SELECT r.a,r.b FROM role r WHERE r.name LIKE '%' AND 1=1 ;DELETE FROM rule WHERE 1=1 ;SELECT * FROM role r WHERE 1=1 AND '%'='%' ORDER BY r.create_time DESC liimit 0,10;
到此一個sql注入語句就出現了,這樣的sql在視覺化介面裡是可以執行通過的,那使用者實際輸入的內容是什麼呢,如下:
%' AND 1=1 ;DELETE FROM rule WHERE 1=1 ;SELECT * FROM role r WHERE 1=1 AND '%'='
當這個構造好的sql到應用程式裡面會發生什麼呢?
當然在我的伺服器裡報錯了,報錯日誌顯示sql語法不對,從delete開始到後面的構造部分。原因就在於PreparedStatement在起作用,具體原理不再敘述。
到這裡就結束了,我沒有在前端發起的注入內容刪除資料。
為啥使用者會這麼輸入呢??
當然是有人惡意攻擊咯,如果真猜出你的資料庫表名並準備實施攻擊的話,那是不是要過一遍自己寫的程式碼或者檢查一下有沒有用PreparedStatement預編譯呢?
或者這是你自己進行的測試,如果你想有PreparedStatement的話是不是就萬事大吉了。
答案是否定的,黑客可不會這麼low.他們想這麼做的話一定有辦法。
雖然你的系統在內網,你的應用訪問量不多,等等,但是我們必須要知道這種威脅的存在,並且防患於未然。
那最好的方式是什麼呢?
1.從產品層面來說要規避使用者輸入特殊字元(不要相信前端輸入的資料),因為正常使用者不會輸入這麼複雜的文字來測試你的程式,我們要做的就是正常請求,正常返回。
2.從技術上來說可以將輸入的特殊字元轉譯。(這個工作可以在前端做,也可在後端)
3.從技術元件來說要從底層使用PreparedStatement進行預編譯。