原文鏈接:https://www.cnblogs.com/chenyoumei/p/8117925.html
1.SQL注入簡介
SQL注入是普通常見的網絡攻擊方式之一,它的原理是通過在參數中輸入特殊符號,來篡改並通過程序SQL語句的條件判斷。
2.SQL注入攻擊的思路
1.判斷應用程序是否存在注入漏洞
判斷方法:在參數后添加單引號" ' ",查看結果,譬如在登錄時,用戶名填為:1' 。或是url鏈接中:http://localhost/course/member/detail?id=1' 。
若是頁面提示報錯或是提示數據庫錯誤的話,即說明存在SQL注入漏洞。
2.收集提示的數據庫報錯信息、判斷數據庫類型、猜解SQL語句、猜解表名、字段名,然后根據SQL注入漏洞與數據表名、字段名等對數據庫進行攻擊。
具體如何猜解,簡而言之就是:根據數據庫報錯信息得出結果,原理很簡單,但是工作量極大,沒有經驗的話,做起來很難。話說回來,如果SQL注入攻擊那么容易的話,數據庫就不用搞了。
這里我只簡單的闡述SQL注入的原理與簡單解決方法,再深入的我就不一一贅述了,有興趣的大家可以自己谷歌。
3.SQL注入攻擊實例
3.1最常見的SQL注入攻擊在用戶登錄這一功能上。
毫無疑問,所有的用戶登錄SQL語句都形如:SELECT * FROM user WHERE name = ' " + userName + " ' and password= ' "+ password +" ';
常見的利用SQL注入攻破用戶登錄,關鍵在於在參數 "name" 或是 "password" 中插入特殊符號,以篡改程序SQL的條件判斷。
譬如我們這樣輸入:
用戶名:1' OR '1'='1
密碼:1
那么程序接收到參數后,SQL語句就變成了:SELECT * FROM user WHERE name = '1' OR '1'='1 ' and password= '1';
恆為真,即可騙過程序,在沒有賬號密碼的情況下成功登錄。
我們也可以這樣輸入:
用戶名:1
密碼:1' OR '1'='1
那么程序接收到參數后,SQL語句就變成了:SELECT * FROM user WHERE name = '1' and password= '1' OR '1'='1 ';
同樣恆為真,也可成功登錄。
若是惡意攻擊數據庫,可以隨意刪除數據庫信息,甚至連數據庫都可以給你刪掉,對項目造成毀滅性的打擊,譬如:
用戶名:1'; DROP DATABASE root;--
密碼:1
那么程序接收到參數后,SQL語句就變成了:SELECT * FROM user WHERE name = '1'; DROP DATABASE root;--and password= '1';
由於分號;是SQL語句結束的標志,它會導致"SELECT * FROM user WHERE name = '1';" 后面的語句成為一條新的SQL語句,而--是SQL語句的單行注釋標志,它會注釋掉"and password= '1';"這一段,使整個SQL語句變的合法。然后 "DROP DATABASE root;"這一句直接把整個root數據庫都刪掉了。
這是被SQL注入攻擊最嚴重的后果。
3.2 此外,只要是輸入參數的SQL語句,都有被SQL注入攻擊的威脅
譬如用戶注冊、用戶個人信息修改、用戶評論等等,凡是輸入參數的地方,都有可能被SQL注入攻擊。
譬如用戶信息修改時,必然要傳遞判斷參數,此時的SQL判斷語句大都形如: UPDATE TABLENAME SET ''='' WHERE ''='' 。例如:update user set avatar='1.jpg' where id='1' 。
而判斷參數有時就在url鏈接中,形如:http://localhost/course/member/detail?id=1 。說明程序很大可能是根據id進行SQL判斷,如果該程序確實是根據用戶id進行SQL判斷。那么直接對url中傳遞的參數 " id=1 " 進行篡改,改成譬如: " id=1'; DROP DATABASE root;-- " ,那好,數據庫root又被刪沒了。
再舉例而言,如果用戶不把判斷參數放到url中,那么一般情況,技術人員把判斷參數放到了保存按鈕上,或是藏在某個隱藏的輸入框里,再有就是cookie中,以及頁面某個不起眼的角落中。此時的判斷參數一般是id、name、phone其中一個,技術人員會通過表單提交或是ajax,將隱藏的判斷參數以post方法提交到后台。此時,只要查看網頁源代碼,一般都能在提交按鈕、隱藏輸入框等角落里找到這個隱藏參數。譬如:<input type="button" name="meizi" onclick="addMember()" value="保存"> 這顯然是一個將判斷參數隱藏到提交按鈕上的以ajax進行post提交的案例,判斷參數為" meizi "。此時,我們按個F12,在源代碼中將" name="meizi" "修改為" name="meizi'; DROP DATABASE root;--",好吧,root又沒了。
4.如何防止SQL注入攻擊
文章開頭,我便說了,SQL注入攻擊的原理就是通過在參數中輸入特殊符號,來篡改並通過程序SQL語句的條件判斷。那么最簡單的辦法就是在禁止用戶向參數中寫入特殊符號,這就是為什么所有網站的用戶名默認不能包含特殊字符的原因。只要在表單提交之前、或是ajax提交之前,對參數進行一下js正則判斷,對含有特殊符號的參數報錯,就不用再擔心SQL注入攻擊啦。
此外,開發項目推薦使用框架編程,框架一般都自帶庫,能檢查參數是否帶有特殊符號。
譬如Thinkphp框架默認轉義特殊符號,在參數中輸入單引號 ' 或是雙引號 " ,都會被默認加上一個 \ 進行轉義,SQL注入攻擊也就失效了。
再譬如,JSP中的PreparedStatement接口對象,會對SQL語句進行預編譯,而SQL注入攻擊只對SQL語句的編譯過程有破壞作用,JSP中使用PreparedStatement接口進行預編譯后,傳入的參數只作為字符串,不會再進行一次編譯,SQL注入攻擊也就失效了。