SQL注入和解決方法
SQL注入
1、SQL 注入說明
應用為了和資料庫進行溝通完成必要的管理和儲存工作,必須和資料庫保留一種介面。目前的資料庫一般都是提供api以支援管理,應用使用底層開發語言如Php,Java,asp,Python與這些api進行通訊。對於資料庫的操作,目前普遍使用一種SQL語言(Structured Query Language語言,SQL語言的功能包括查詢、操縱、定義和控制,是一個綜合的、通用的關係資料庫語言,同時又是一種高度非過程化的語言,只要求使用者指出做什麼而不需要指出怎麼做),SQL作為字串通過API傳入給資料庫,資料庫將查詢的結果返回,資料庫自身是無法分辨傳入的SQL是合法的還是不合法的,它完全信任傳入的資料,如果傳入的SQL語句被惡意使用者控制或者篡改,將導致資料庫以當前呼叫者的身份執行預期之外的命令並且返回結果,導致安全問題。
2、SQL注入影響
惡意使用者利用SQL注入可以做到:
1、可讀取資料庫中的庫和表
2、可執行系統命令
3、可以修改任意檔案
4、可以安裝木馬後門
3、SQL注入示例
以下分別是JAVA和PHP的有SQL注入漏洞的程式碼示例:
Java(jdbc)示例:
HttpServletRequest request, HttpServletResponse response) { JdbcConnection conn = new JdbcConnection(); final String sql = "select * from product where pname like '%" + request.getParameter("name") + "%'"; conn.execqueryResultSet(sql); |
Java(ibatis)示例
<select id="unsafe" resultMap="myResultMap"> select * from table where name like '%$value$%' </select> UnSafeBean b = (UnSafeBean)sqlMap.queryForObject("value", request.getParameter("name")); |
PHP示例:
$sql = "select * from product where pname like '%" .$_REQUEST["name"] . "%'"; mysqli_query($link,$sql); |
當呼叫以上程式碼做資料庫查詢時,name被拼接到SQL查詢語句中,便會造成SQL注入漏洞的出現。
使用者提交http://localhost:8080/struts1/listProduct.htm?pname=e' and 1=2 union select 1,name,pass,4 from user where ''<>'便會執行對USER表的查詢。
根據以上原理,使用者可以構造任意SQL語句查詢資料庫,甚至執行系統命令。
4、SQL注入解決方法
解決SQL注入問題的關鍵是對所有可能來自使用者輸入的資料進行嚴格的檢查、對資料庫配置使用最小許可權原則。
1、所有的查詢語句都使用資料庫提供的引數化查詢介面,引數化的語句使用引數而不是將使用者輸入變數嵌入到SQL語句中。當前幾乎所有的資料庫系統都提供了引數化SQL語句執行介面,使用此介面可以非常有效的防止SQL注入攻擊。
2、對進入資料庫的特殊字元(’”\尖括號&*;等)進行轉義處理,或編碼轉換。
3、嚴格限制變數型別,比如整型變數就採用intval()函式過濾,資料庫中的儲存欄位必須對應為int型。
4、資料長度應該嚴格規定,能在一定程度上防止比較長的SQL注入語句無法正確執行。
5、網站每個資料層的編碼統一,建議全部使用UTF-8編碼,上下層編碼不一致有可能導致一些過濾模型被繞過。
6、嚴格限制網站使用者的資料庫的操作許可權,給此使用者提供僅僅能夠滿足其工作的許可權,從而最大限度的減少注入攻擊對資料庫的危害。
7、避免網站顯示SQL錯誤資訊,比如型別錯誤、欄位不匹配等,防止攻擊者利用這些錯誤資訊進行一些判斷。
8、在網站釋出之前建議使用一些專業的SQL注入檢測工具進行檢測,及時修補這些SQL注入漏洞。
9、確認PHP配置檔案中的magicquotesgpc選項保持開啟
JSP防止SQL注入參考程式碼
正常查詢 conn = createConnection(); String sql = "select name,password from manager where name=? and password=?"; stat = conn.prepareStatement(sql); stat.setString(1, name); stat.setString(2, password); stat.executeQuery(sql); 模糊查詢 conn = createConnection(); String sql = "select * from table where url like ?"; stat = con.prepareStatement(sql); String data="data"; stat.setString(1, "%"+data+"%"); stat.executeQuery(sql); |