24、SQL注入是什么,如何避免SQL注入?
SQL 注入(SQL Injection)是發生在 Web 程序中數據庫層的安全漏洞,是網站存在最多也是最簡單的漏洞。主要原因是程序對用戶輸入數據的合法性沒有判斷和處理,導致攻擊者可以在 Web 應用程序中事先定義好的 SQL 語句中添加額外的 SQL 語句,在管理員不知情的情況下實現非法操作,以此來實現欺騙數據庫服務器執行非授權的任意查詢,從而進一步獲取到數據信息。
簡而言之,SQL 注入就是在用戶輸入的字符串中加入 SQL 語句,如果在設計不良的程序中忽略了檢查,那么這些注入進去的 SQL 語句就會被數據庫服務器誤認為是正常的 SQL 語句而運行,攻擊者就可以執行計劃外的命令或訪問未被授權的數據。
SQL 注入已經成為互聯網世界 Web 應用程序的最大風險,我們有必要從開發、測試、上線等各個環節對其進行防范。下面介紹 SQL 注入的原理及避免 SQL 注入的一些方法。
SQL注入的原理
SQL 注入的原理主要有以下 4 點:
1)惡意拼接查詢
我們知道,SQL 語句可以查詢、插入、更新和刪除數據,且使用分號來分隔不同的命令。例如:
SELECT * FROM users WHERE user_id = $user_id其中,user_id 是傳入的參數,如果傳入的參數值為“1234; DELETE FROM users”,那么最終的查詢語句會變為:
SELECT * FROM users WHERE user_id = 1234; DELETE FROM users如果以上語句執行,則會刪除 users 表中的所有數據。
2)利用注釋執行非法命令。
SQL 語句中可以插入注釋。例如:
SELECT COUNT(*) AS 'num' FROM game_score WHERE game_id=24411 AND version=$version如果 version 包含了惡意的字符串’-1’ OR 3 AND SLEEP(500)–,那么最終查詢語句會變為:
SELECT COUNT(*) AS 'num' FROM game_score WHERE game_id=24411 AND version='-1' OR 3 AND SLEEP(500)--以上惡意查詢只是想耗盡系統資源,SLEEP(500) 將導致 SQL 語句一直運行。如果其中添加了修改、刪除數據的惡意指令,那么將會造成更大的破壞。
3)傳入非法參數
SQL 語句中傳入的字符串參數是用單引號引起來的,如果字符串本身包含單引號而沒有被處理,那么可能會篡改原本 SQL 語句的作用。 例如:
SELECT * FROM user_name WHERE user_name = $user_name如果 user_name 傳入參數值為 G’chen,那么最終的查詢語句會變為:
SELECT * FROM user_name WHERE user_name ='G'chen'一般情況下,以上語句會執行出錯,這樣的語句風險比較小。雖然沒有語法錯誤,但可能會惡意產生 SQL 語句,并且以一種你不期望的方式運行。
4)添加額外條件
在 SQL 語句中添加一些額外條件,以此來改變執行行為。條件一般為真值表達式。例如:
UPDATE users SET userpass='$userpass' WHERE user_id=$user_id;如果 user_id 被傳入惡意的字符串“1234 OR TRUE”,那么最終的 SQL 語句會變為:
UPDATE users SET userpass= '123456' WHERE user_id=1234 OR TRUE;這將更改所有用戶的密碼。
避免SQL注入
對于 SQL 注入,我們可以采取適當的預防措施來保護數據安全。下面是避免 SQL 注入的一些方法。
1. 過濾輸入內容,校驗字符串
過濾輸入內容就是在數據提交到數據庫之前,就把用戶輸入中的不合法字符剔除掉??梢允褂镁幊陶Z言提供的處理函數或自己的處理函數來進行過濾,還可以使用正則表達式匹配安全的字符串。
如果值屬于特定的類型或有具體的格式,那么在拼接 SQL 語句之前就要進行校驗,驗證其有效性。比如對于某個傳入的值,如果可以確定是整型,則要判斷它是否為整型,在瀏覽器端(客戶端)和服務器端都需要進行驗證。
2. 參數化查詢
參數化查詢目前被視作是預防 SQL 注入攻擊最有效的方法。參數化查詢是指在設計與數據庫連接并訪問數據時,在需要填入數值或數據的地方,使用參數(Parameter)來給值。
MySQL 的參數格式是以“?”字符加上參數名稱而成,如下所示:
UPDATE myTable SET c1 = ?c1, c2 = ?c2, c3 = ?c3 WHERE c4 = ?c4在使用參數化查詢的情況下,數據庫服務器不會將參數的內容視為 SQL 語句的一部分來進行處理,而是在數據庫完成 SQL 語句的編譯之后,才套用參數運行。因此就算參數中含有破壞性的指令,也不會被數據庫所運行。
3. 安全測試、安全審計
除了開發規范,還需要合適的工具來確保代碼的安全。我們應該在開發過程中應對代碼進行審查,在測試環節使用工具進行掃描,上線后定期掃描安全漏洞。通過多個環節的檢查,一般是可以避免 SQL 注入的。
有些人認為存儲過程可以避免 SQL 注入,存儲過程在傳統行業里用得比較多,對于權限的控制是有一定用處的,但如果存儲過程用到了動態查詢,拼接 SQL,一樣會存在安全隱患。
下面是在開發過程中可以避免 SQL 注入的一些方法。
1. 避免使用動態SQL
避免將用戶的輸入數據直接放入 SQL 語句中,最好使用準備好的語句和參數化查詢,這樣更安全。
2. 不要將敏感數據保留在純文本中
加密存儲在數據庫中的私有/機密數據,這樣可以提供了另一級保護,以防攻擊者成功地排出敏感數據。
3. 限制數據庫權限和特權
將數據庫用戶的功能設置為最低要求;這將限制攻擊者在設法獲取訪問權限時可以執行的操作。
4. 避免直接向用戶顯示數據庫錯誤
攻擊者可以使用這些錯誤消息來獲取有關數據庫的信息。
一些編程框架對于寫出更安全的代碼也有一定的幫助,因為它提供了一些處理字符串的函數和使用查詢參數的方法。但同樣,你仍然可以編寫出不安全的 SQL 語句。所以歸根到底,我們需要有良好的編碼規范,并能充分利用參數化查詢、字符串處理和參數校驗等多種辦法來保護數據庫和程序的安全。
說明:SQL 注入技術不是單憑一篇文章就可以講完的,這里只帶領大家掌握 SQL 注入的原理及常見的幾種防止 SQL 注入的方法。
總結
以上是生活随笔為你收集整理的24、SQL注入是什么,如何避免SQL注入?的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 13、 LEFT/RIGHT JOIN:
- 下一篇: 4、MySQL冷备份所需物理文件