1. 程式人生 > >記一次sql注入實踐

記一次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進行預編譯。