背景
我已经签约分析现有的数据提供者,我知道以下代码有问题;但是为了指出它是多么糟糕,我需要证明它是易于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; --'
My.Computer.Clipboard.SetText(input)
并且您需要将您需要的字符串复制到剪贴板上,粘贴到网站上的输入字段以完成sql注入:
'; Drop Table TableName; - -
[注意到StackOverflow的后输出中省略了控制字符,所以你必须遵循代码示例来创建你的输出]
在运行PrepareString方法之后,它将具有完全相同的输出–Chr(8)ASCII代码是退格键,它会删除你附加到我的额外的“’”,这将关闭你的字符串,然后我自由添加任何我想要的结束。您的PrepareString看不到我 – 因为我实际上正在使用 – – 使用退格键删除空格。
所生成的sql代码将会不受阻碍地执行我的Drop Table语句,并且会立即忽略您的其余查询。
有趣的是,您可以使用不可打印的字符来基本上绕过您可以发明的任何字符检查。所以使用参数化查询是最安全的(这不是你所问的,而是避免这种情况的最佳途径)。