介紹: SQL是一種用於關系數據庫的結構化查詢語言。它分為許多種,但大多數都松散地基於美國國家標准化組織最新的標准SQL-92。典型的執行語句是query,它能夠收集比較有達標性的記錄並返回一個單一的結果集。SQL語言可以修改數據庫結構(數據定義語言)和操作數據庫內容(數據操作語言)。在這份文檔中,我們將特別討論SQLSERVER所使用的Transact-SQL語言。
當一個攻擊者能夠通過往query中插入一系列的sql語句來操作數據寫入到應用程序中去,我們管這種方法定義成SQL注入。
一個典型的SQL語句如下:
Select id,forename,surname from authors
這條語句將返回authors表中所有行的id,forename和surname列。這個結果可以被限制,例如:
Select id,forename,surname from authors where forename'john' and surname='smith'
需要著重指明的是字符串'john'和'smith'被單引號限制。明確的說,forename和surname字段是被用戶提供的輸入限制的,攻擊者可以通過輸入值來往這個查詢中注入一些SQL語句,
如下:
Forename:jo'hn
Surname:smith
查詢語句變為:
Select id,forename,surname from authors where forename='jo'hn' and surname='smith'
當數據庫試圖去執行這個查詢時,它將返回如下錯誤:
Server:Msg 170, Level 15, State 1, Line 1
Line 1:Incorrect syntax near 'hn'
造成這種結果的原因是插入了.作為定界符的單引號。數據庫嘗試去執行'hn',但是失敗。如果攻擊者提供特別的輸入如:
Forename:jo';drop table authors—
Surname:
結果是authors表被刪除,造成這種結果的原因我們稍後再講。
看上去好象通過從輸入中去掉單引號或者通過某些方法避免它們都可以解決這個問題。這是可行的,但是用這種方法做解決方法會存在幾個困難。第一,並不是所有用戶提供的數據都是字符串。如果用戶輸入的是通過用戶id來查詢author,那我們的查詢應該像這樣:
Select id,forename,surname from authors where id=1234
在這種情況下,一個攻擊者可以非常簡單地在數字的結尾添加SQL語句,在其他版本的SQL語言中,使用各種各樣的限定符號;在數據庫管理系統JET引擎中,數據可以被使用'#'限定。第二,避免單引號盡管看上去可以,但是是沒必要的,原因我們稍後再講。
我們更進一步地使用一個簡單的ASP登陸頁面來指出哪些能進入SQLSERVER數據庫並且嘗試鑒別進入一些虛構的應用程序的權限。
這是一個提交表單頁的代碼,讓用戶輸入用戶名和密碼:
<Html>
<HEAD>
<TITLE>Login Page</TITLE>
</HEAD>
<BODY bgcolor='000000' text='cccccc'>
<FONT Face='tahoma' color='cccccc'>
<CENTER><H1>Login</H1>
<FORM action='process_loginASP' method=post>
<TABLE>
<TR><TD>Username:</TD><TD><INPUT type=text name=username size=100 width=100></TD></TR>
<TR><TD>Password:</TD><TD><INPUT type=passWord