Dot-Net
此程式碼是否防止 SQL 注入?
背景
我已簽約分析現有的數據提供者,我知道以下程式碼有問題;但為了指出它有多糟糕,我需要證明它容易受到 SQL 注入的影響。
題
什麼“Key”參數可以破壞
PrepareString函式並允許我執行DROP語句?程式碼片段
Public Shared Function GetRecord(ByVal Key As String) As Record Dim Sql As New StringBuilder() With Sql .Append("SELECT * FROM TableName") If String.IsNullOrEmpty(Agency) Then .Append(" ORDER BY DateAdded") Else .Append(" WHERE Key = '") .Append(PrepareString(Key)) .Append("'") End If End With Return ExecuteQuery(Sql.ToString()) End Function Public Shared Function PrepareString(ByVal Value As String) As String Return Value.Replace("''", "'") _ .Replace("'", "''") _ .Replace("`", "''") _ .Replace("´", "''") _ .Replace("--", "") End Function
回答您的直接問題:此程式碼是否防止 SQL 注入:否
這是證明 - 通過 PrepareString 方法推送此字元串:
Dim input = "'" & Chr(8) & "; Drop Table TableName; - " & Chr(8) & "-" Dim output = PrepareString(input) Console.WriteLine(input) Console.WriteLine(output)我修改了您發布的 GetRecord 方法以返回完全準備好的 SQL 字元串,而不是從數據庫中獲取記錄:
Console.WriteLine(GetRecord(output))這是輸出
Input = ; Drop Table TableName; -- Output = '; Drop Table TableName; -- Query = SELECT * FROM TableName WHERE Key = ''; Drop Table TableName; --'添加 1 行額外的程式碼:
My.Computer.Clipboard.SetText(input)您已經將需要的字元串複製到剪貼板,以粘貼到網站上的輸入欄位中,以完成 SQL 注入:
'; Drop Table TableName; - -[請注意,StackOverflow 的文章輸出中省略了控製字元,因此您必須按照程式碼範例來創建輸出]
執行 PrepareString 方法後,它將具有完全相同的輸出 - Chr(8) ASCII 程式碼是退格,它將刪除您附加到我的額外的“’”,這將關閉您的字元串,然後我最後自由添加我想要的任何東西。您的 PrepareString 看不到我的 – 因為我實際上正在使用 – 帶有退格字元來刪除空格。
然後,您正在建構的生成的 SQL 程式碼將不受阻礙地執行我的 Drop Table 語句,並立即忽略其餘的查詢。
有趣的是,您可以使用不可列印的字元基本上繞過您可以發明的任何字元檢查。因此,使用參數化查詢是最安全的(這不是您所要求的,但這是避免這種情況的最佳途徑)。