Web十大安全隱患之SQL注入
注入往往是應用程序缺少對輸入進行安全性檢查所引起的,攻擊者把一些包含指令的數據發送給解釋器,解釋器會把收到的數據轉換成指令執行。常見的注入包括SQL注入,OS Shell,LDAP,Xpath,Hibernate等等,而其中SQL注入尤為常見。這種攻擊所造成的后果往往很大,一般整個數據庫的信息都能被讀取或篡改,通過SQL注入,攻擊者甚至能夠獲得更多的包括管理員的權限。
先來說說sql注入漏洞是怎么產生的,或者說對于一個程序開發人員應該怎么防范SQL注入的吧。
SQL注入往往是在編寫包含用戶輸入的動態數據庫查詢時產生的,但其實防范SQL注入的方法非常簡單。程序員只不再寫動態查詢,或防止用戶輸入包含能夠破壞查詢邏輯的惡意SQL語句,就能夠防范SQL注入。當然,我作為一個測試人員說起來很容易,做起來就難了。
我本人只會java,所以后邊我就用Java代碼作為示例:
<font face="宋體" color="#000000">String query ="SELECT account_balance FROM user_data WHERE user_name =" + request.getParameter("customerName"); try { Statement statement = connection.createStatement( …); ResultSet results = Statement.executeQuery(query); }</font> |
在以上代碼中,我們可以看到并未對變量customerName做驗證,customerName的值可以直接附在query語句的后面傳送到數據庫執行,那么攻擊者可以將任意的sql語句注入。
上邊說到怎么產生的,我們接著說怎么樣才能讓sql注入的漏洞避免。本來計劃把這一段放在如何測試之后再介紹,但是貌似先介紹出來更方便理解。
防范方法一 :參數化查詢
參數化查詢是所有開發人員在做數據庫查詢時首先需要學習的,參數化查詢迫使所有開發者首先要定義好所有的SQL代碼,然后再將每個參數逐個傳入,這種編碼風格就能夠讓數據庫辨明代碼和數據。
參數化查詢能夠確保攻擊者無法改變查詢的內容,在下面修正過的例子中,如果攻擊者輸入了UsrID是“’or ‘1 ‘=’1”,參數化查詢會去查找一個完全滿足名字為‘or ‘1 ‘=’ 1的用戶。
對于不同編程語言,有一些不同的建議:
Java——使用帶綁定變量的PreparedStatement();
其他的:。。。不好意思,真不會
示例:
<font face="宋體" color="#000000">String custname = request.getParameter("customerName"); String query ="SELECT account_balance FROM user_data WHERE user_name= ?"; PreparedStatement pstmt = connection.prepareStatement(query); Pstmt.setString1,custname(); ResultSet results = pstmt.executeQuery();</font> |
防范方法二:存儲過程
存儲過程和參數化查詢的作用是一樣的,唯一的不同在于存儲過程是預先定義并存放在數據庫中,從而被應用程序調用的。
Java存儲過程示例:
String custname = request.getParameter("customerName"); try { CallableStatement cs = connection.prepareCall("call sp_getAccountBalance(?)}"); cs.setString(1,custname); Result results = cs.executeQuery(); }catch(SQLException se){ //error handling } |
posted on 2013-12-09 10:39 順其自然EVO 閱讀(329) 評論(0) 編輯 收藏 所屬分類: 安全性測試