我试图在这里简单地证明这个简单的函数不足以阻止世界上的每一次sql注入:
Function CleanForSQL(ByVal input As String) As String Return input.Replace("'", "''") End Function
这是来自我们其中一个应用程序的典型插入语句:
Database.DBUpdate("UPDATE tblFilledForms SET Text1 = '" + CleanForSQL(txtNote.Text) + "' WHERE FilledFormID = " + DGVNotes.SelectedRows(0).Cells("FilledFormID").Value.ToString)
我知道它是不安全的,因为进行了谷歌搜索和查找其他问题。 这是我发现的一个问题,其中所有功能(例如我上面介绍的功能)都不相关且毫无意义。
因此,根据我链接到的帖子,只需键入
‘Chr(8); 更新tblMaint SET Value1 = 2 WHERE ValueID = 2-
插入txtNote应该足以清除整个tblFilledForms表中text1中的每个值,然后将tblmaint表的第二行更新为2正确吗?
这里应该发生的是VB将其解释为
更新tblFilledForms SET Text1 =’‘’Chr(8); 更新tblMaint SET Value1 = 2 WHERE ValueID = 2–‘WHERE FilledFormID = 5120327
并将其发送到SQL,这将实习生执行Chr(8)以擦除将产生的第三个’
更新tblFilledForms SET Text1 =’‘; 更新tblMaint SET Value1 = 2 WHERE ValueID = 2–‘WHERE FilledFormID = 5120327
在数据库上实际执行正确吗?
然后,我从剪贴板中复制了一个Chr(8),并用剪贴板中的内容替换了文本框中的Chr(8),但还是不行。它将整个字符串直接放入没有问题的字段中。
那么,我在这里做错了什么? 还是我可以做些什么来打破它?
技术和背景:我正在使用MS SQL Server 2005和VB .NET2005。数据库中的Text1字段是Varchar(600)字段(不要问我为什么它不是MAX,它没有意义,我知道)表格上的某些触发器会阻止此类大规模更新,并且如果进样确实正确,则会引发一些错误。
PS。我知道参数化查询是解决此问题的方法,我不是在寻找诸如“好吧,我不知道为什么它不起作用,但是参数化查询才是解决之道”之类的答案。我正在寻找能够证明我们的软件已损坏并且需要使用更好的原理重写它的能力。
对于阅读此问题以弄清楚如何更好地过滤文本字段的任何人,答案是不要!使用参数!它们变得更好,更安全,更容易!
Chr(8)是带引号的文字字符串的一部分,与update语句一样,因此SQL Server不会将其解释为函数调用。在此示例中,Text1将设置为文字值:
'Chr(8); update tblMaint SET Value1 = 2 WHERE ValueID = 2--
(是的,包括单引号)
因此,在此示例中,您的代码 是 安全的。SQL注入的大多数困扰在于偶然地 未能 验证和引用值,在正确引用的SQL语句中没有天生不安全的问题。