Dot-Net

此程式碼是否防止 SQL 注入?

  • December 16, 2012

背景

我已簽約分析現有的數據提供者,我知道以下程式碼有問題;但為了指出它有多糟糕,我需要證明它容易受到 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 語句,並立即忽略其餘的查詢。

有趣的是,您可以使用不可列印的字元基本上繞過您可以發明的任何字元檢查。因此,使用參數化查詢是最安全的(這不是您所要求的,但這是避免這種情況的最佳途徑)。

引用自:https://stackoverflow.com/questions/1800013