update users set password = 'passWord' where username = 'admin'--'
因此攻擊者可以通過注冊了一個名叫admin'--的用戶來把admin的密碼改成他們自己的。
這是個危險的問題,目前大部分的大型程序都試圖過濾數據。最好的解決方法是拒絕非法輸入,而不是簡單的改變它。這有時候會導致一些問題,非法字符在某些地方是必要的,比如在名字帶符號的情況:
O'BrIEn
從安全的角度,最好的解決辦法是不允許出現單引號。如果這樣不行,必須避免它們出現,這種情況下,最好保證所有要進入SQL語句的字符(包括從數據庫裡取出的字符)都被正確的處理過。
即使這樣攻擊依然可能實現:如果攻擊者可以不經過程序而往系統插入數據。比如攻擊者有一個email接口,或者有一個可以控制的錯誤記錄數據庫。最好總是驗證所有的數據,包括系統裡的數據,驗證函數調用很簡單,比如:
if ( not isValIEd( "email", request.querystring("emil") ) ) then
response.end
或者其他的方法
[長度限制]
有時候輸入對數據的長度加以限制會使攻擊困難許多,這的確阻止了一些攻擊,但一個很短的SQL語句也可能造成非常大的危害:
Username: ';shutdown--
關閉SQL-Server,只用了12個字符。另一個例子:
drop table
如果長度限制是在字符串過濾後,另一個問題可能會發生。假設用戶名被限制在16個字符之內,密碼也被限制在16個字符之內,下面的用戶名和密碼結合可以執行'shutdown'命令:
Username:aaaaaaaaaaaaaaa'
PassWord:'; shutdown--
原因是程序過濾用戶名最後的單引號,但是字符串又被切回到16個字符,刪除了過濾的單引號。結果是密碼域可以包含一些SQL, 只要它以一個單引號開始,最後的查詢會變成這樣:
select * from users where username = 'aaaaaaaaaaaaaa'' and passWord=''';shutdown--
用戶名在查詢裡就變成:
aaaaaaaaaaaaaaa' and passWord='
後面附上的SQL被執行。
[躲避審核]
SQL Server在sp_traceXXX系列的函數包含豐富審核接口,它可以記錄任何數據庫裡的事件。這裡我們特別感興趣的是T-SQL事件,它記錄了所有的SQL語句以及服務器上准備好的和已運行了的批處理。如果這個級別的審核開啟的話,所有我們討論的注入都將被記錄下來有經驗的數據庫管理員將會看到所有發生的事情。但是如果攻擊者附加下面的字符:
sp_passWord
到一個Transact-SQL語句,這個審核記錄如下:
-- 'sp_passWord' was found in the text of this event.
-- The text has been replaced with this comment for security reasons.
這在所有的的T-SQL日志記錄時都會發生,即使'sp_password'出現在注釋中。這當然是在用戶傳遞sp_passWord時有意隱藏用戶的明文密碼,但這對攻擊者相當有用。
所以,為了隱藏所有的注入攻擊者只需要在注釋符'--'後面加一個字符串:
Username: admin'--sp_passWord
事實上一些執行了的SQL將被記錄,但是查詢字符串本身被強制不記錄。
[防 范]
這部分討論一些針對這些攻擊的防范措施。輸入驗證已經討論過了,一些代碼也給出了,後面我們研究SQL-Server防范問題。
[輸入驗證]
輸入驗證是一個很復雜的問題。一般在一個開發項目中它很少被注意,因為過度的驗證往往使一個程序的某部分被打斷,所以輸入驗證是個難題。輸入驗證往往不加到程序的功能裡,因而在工期將至而趕程序時不會被人注意。
下面是關於驗證的簡單的討論附示例代碼,這個示例代碼當然不能直接用在程序裡,但可以很好的說明不同的策略。
各種數據驗證的途徑可以分類為以下幾種:
1)整理數據使之變得有效
2)拒絕已知的非法輸入
3)只接受已知的合法的輸入
有很多概念上的問題;首先,開發者沒有必要知道非法數據由什麼組成,因為新形式的非法數據隨時都可能產生。第二,改變數據會改變它的長度,這樣會導致前面提到的問題。最後,還有需要對系統已有數據的重用的話有二次注入的問題.
解決方案2也會遇到和1的一些相似的問題,了解非法數據會過時,因為新的攻擊技術也在發展。
解決方案3可能是三種方法中最好的,但是比較難於執行。
從安全角度來考慮可能最好多解決方法是把解決方案2和3結合起來只允許合法的輸入,然後再尋找非法字符。
一個必須結合這兩種途徑的例子是帶有連字符的名字的問題:
Question Bassington-Bassington
我們必須在合法輸入裡允許連字符號,但是也要明白字符串'--'在SQL-Server裡意味著什麼。
當數據整理結合了非法字符驗證時另一個問題就會發生。假設我們應用“非法字符探測器”來探測'--','select'和'union'”後使用“數據整理過濾器”刪除單引號,攻擊者就可以指定這樣的輸入: