sql 注入(sql injection)是發生在 web 程式中資料庫層的安全漏洞,是**存在最多也是最簡單的漏洞。主要原因是程式對使用者輸入資料的合法性沒有判斷和處理,導致攻擊者可以在 web 應用程式中事先定義好的 sql 語句中新增額外的 sql 語句,在管理員不知情的情況下實現非法操作,以此來實現欺騙資料庫伺服器執行非授權的任意查詢,從而進一步獲取到資料資訊。
簡而言之,sql 注入就是在使用者輸入的字串中加入 sql 語句,如果在設計不良的程式中忽略了檢查,那麼這些注入進去的 sql 語句就會被資料庫伺服器誤認為是正常的 sql 語句而執行,攻擊者就可以執行計畫外的命令或訪問未被授權的資料。
sql 注入已經成為網際網路世界 web 應用程式的最大風險,我們有必要從開發、測試、上線等各個環節對其進行防範。下面介紹 sql 注入的原理及避免 sql 注入的一些方法。
sql 注入的原理主要有以下 4 點:
我們知道,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 表中的所有資料。
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'or3
and sleep(
500)
--
以上惡意查詢只是想耗盡系統資源,sleep(500) 將導致 sql 語句一直執行。如果其中新增了修改、刪除資料的惡意指令,那麼將會造成更大的破壞。
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 語句,並且以一種你不期望的方式執行。
在 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
ortrue
;
這將更改所有使用者的密碼。
對於 sql 注入,我們可以採取適當的預防措施來保護資料安全。下面是避免 sql 注入的一些方法。
過濾輸入內容就是在資料提交到資料庫之前,就把使用者輸入中的不合法字元剔除掉。可以使用程式語言提供的處理函式或自己的處理函式來進行過濾,還可以使用正規表示式匹配安全的字串。
如果值屬於特定的型別或有具體的格式,那麼在拼接 sql 語句之前就要進行校驗,驗證其有效性。比如對於某個傳入的值,如果可以確定是整型,則要判斷它是否為整型,在瀏覽器端(客戶端)和伺服器端都需要進行驗證。
引數化查詢目前被視作是預防 sql 注入攻擊最有效的方法
。引數化查詢是指在設計與資料庫連線並訪問資料時,在需要填入數值或資料的地方,使用引數(parameter)來給值。
mysql 的引數格式是以「?」字元加上引數名稱而成,如下所示:
update mytable set c1 = ?c1, c2 = ?c2, c3 = ?c3 where c4 = ?c4
在使用引數化查詢的情況下,資料庫伺服器不會將引數的內容視為 sql 語句的一部分來進行處理,而是在資料庫完成 sql 語句的編譯之後,才套用引數執行。因此就算引數中含有破壞性的指令,也不會被資料庫所執行。
除了開發規範,還需要合適的工具來確保**的安全。我們應該在開發過程中應對**進行審查,在測試環節使用工具進行掃瞄,上線後定期掃瞄安全漏洞。通過多個環節的檢查,一般是可以避免 sql 注入的。
有些人認為儲存過程可以避免 sql 注入,儲存過程在傳統行業裡用得比較多,對於許可權的控制是有一定用處的,但如果儲存過程用到了動態查詢,拼接 sql,一樣會存在安全隱患。
1. 避免使用動態sql
避免將使用者的輸入資料直接放入 sql 語句中,最好使用準備好的語句和引數化查詢,這樣更安全。
2. 不要將敏感資料保留在純文字中
加密儲存在資料庫中的私有/機密資料,這樣可以提供了另一級保護,以防攻擊者成功地排出敏感資料。
3. 限制資料庫許可權和特權
將資料庫使用者的功能設定為最低要求;這將限制攻擊者在設法獲取訪問許可權時可以執行的操作。
4. 避免直接向使用者顯示資料庫錯誤
攻擊者可以使用這些錯誤訊息來獲取有關資料庫的資訊。
一些程式設計框架對於寫出更安全的**也有一定的幫助,因為它提供了一些處理字串的函式和使用查詢引數的方法。但同樣,你仍然可以編寫出不安全的 sql 語句。所以歸根到底,我們需要有良好的編碼規範,並能充分利用引數化查詢、字串處理和引數校驗等多種辦法來保護資料庫和程式的安全。
SQL注入是什麼?如何防止?
sql注入是一種注入攻擊,可以執行惡意sql語句。下面本篇文章就來帶大家了解一下sql注入,簡單介紹一下防止sql注入攻擊的方法,希望對大家有所幫助。什麼是sql注入?sql注入 sqli 是一種注入攻擊,可以執行惡意sql語句。它通過將任意sql 插入資料庫查詢,使攻擊者能夠完全控制web應用程式...
SQL注入是什麼?
許多 程式在編寫時,沒有對使用者輸入資料的合法性進行判斷,使應用程式存在安全隱患。使用者可以提交一段資料庫查詢 一般是在瀏覽器位址列進行,通過正常的www埠訪問 根據程式返回的結果,獲得某些想得知的資料,這就是所謂的sql injection,即sql注入。的惡夢 sql注入 sql注入通過網頁對 ...
什麼是sql注入 如何防止sql注入
sql注入 利用現有應用程式,將 惡意 的sql命令注入到後台資料庫執行一些惡意的操作 造成sql注入的原因是因為程式沒有有效過濾使用者的輸入,使攻擊者成功的向伺服器提交惡意的sql查詢 程式在接收後錯誤的將攻擊者的輸入作為查詢語句的一部分執行,導致原始的查詢邏輯被改變,額外的執行了攻擊者精心構造的...