對SQL注入的一點思考

ASP網頁的一大安全問題是SQL注入問題。之所以SQL語句能被注入,是因爲輸入的參數有可能會被當作代碼的一部分而被執行,即被當作“元語言”處理。在ASP中,我們一般這樣構造SQL語句:sql="select * from table where id='" & id & "'",我們期望輸入的id參數被當作“目標語言”,然而,給id一個特殊的串值,它依然可能被當作代碼執行。id周圍加了“'”,使得“?id=1 and 1=1”不好使了,然而id裏面完全也可以包含“'”來繞過這道“防線”,比如“?id=1' and '1'='1”。

一種簡單的解決辦法就就是在參數周圍加“'”並用以下這段代碼對參數處理一下:

Function SafeRequest(ParaName,ParaType)
  'ParaName:參數名稱-字符型
  'ParaType:參數類型-數字型(1表示以上參數是數字,0表示以上參數爲字符)
  Dim ParaValue
  ParaValue=Request(ParaName)
  If ParaType=1 then
    If not isNumeric(ParaValue) then
      Response.write "參數" & ParaName & "必須爲數字型!"
      Response.end
    End if
  Else
    ParaValue=replace(ParaValue,"'","''")
  End if
  SafeRequest=ParaValue
End function

可以看出,這段代碼就是把“'”換成了“目標語言”的表示形式(當然還有判斷應該是數字的參數的實際值是否爲數字的功能)。

回憶DOS窗口編程的時代,輸入的是變量的值,用來被程序處理,頂多用來作爲控制信息。所以不會被“注入”(當然,那個時代也有那個時代有攻擊方式,比如說緩衝區溢出)。

想起HDLC協議,字節“01111110”是一個幀的開始標誌和結束標誌,也即“元語言”,若數據中出現“01111110”,則必須將其替換掉防止系統把它當作“元語言”處理,方法爲若遇到連續5個“1”,則在後面自動加一個“0”,也即“0”比特插入法。

對JSP,JDBC中的PreparedStatement先構造一個帶一串“問號”的SQL語句,然後再將“問號”處填入,系統通過替換手段嚴格將填入的東西當作目標語言處理,因此可以防止SQL注入。

對於設計一種“語言”(不一定是編程語言啦,可以是用戶與系統交互的語言、通信協議語言、分層結構軟件層與層之間交互的語言等等)來講,把“元語言”跟“目標語言”搞清楚還是很有必要的。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章