我正在尝试与SQL Server接口MS访问,我想确保我不容易受到SQL注入攻击的影响。
我已经看到了使用ADO创建疑问的优势版本的建议,但是我想学习如何通过DAO通过。
目前,我逃脱了单语引号和反闪烁。
VBA中是否有任何标准的SQL Server注入卫生方法?
vba中是否有任何标准的SQL Server注入卫生方法?
nope。我会很担心是否有。我不做PHP,但我读了有关其"标准SQL注入卫生方法"的恐怖故事。只需窥视使用PHP和SQL标记的代码评论问题 - 很多都在问"此代码安全吗?"的变体,除非他们使用准备好的语句,答案总是总是"否"。
');--DROP TABLE Users;--
是在UserName
数据库字段中看到的一个相当可疑的价值(您认为该答案的文本在哪里存储?),但是,如果您正确编写了数据访问代码,则没有理由引起它即使您的登录名(服务器端)执行此类语句,即使您的登录名。
问题不是用户的输入。问题是串联用户输入到可执行的SQL 中,因此将用户输入视为可执行的代码。
您的想要是执行常数 sql语句。当您这样做时:
' *** DON'T DO THIS ***
Dim sql As String
sql = "SELECT Id FROM dbo.Users WHERE UserName = '" & pName & "';"
然后,每当SQL语句发送到服务器时,这是一个不同的查询:服务器甚至不知道涉及参数,它所看到的只是以下内容:
SELECT Id FROM dbo.Users WHERE UserName = ''');--DROP TABLE Users;--';
注意额外的单报价;如果您想嘿,SQL注入是可以预防的,那么您会忘记并不是因为您不能打败您的输入消毒,没有人可以。许多公司都使用这种"预防注射"的网站,并且 Think 他们的代码是安全的。当他们在Twitter上吹牛说"与网上的十年都没有被黑客入侵"时,全球的脚本孩子需要几分钟才能将其拆除。不能打扰挖一个链接,但是这个确切的故事发生了,而是最近发生的。
当您通过ADO发送参数化查询时,这是服务器收到的内容:
SELECT Id FROM dbo.Users WHERE UserName = ?;
注意查询不知道甚至不需要照顾参数的类型及其周围的单引号。
注意,无论用户输入是什么。
请注意,参数值甚至没有接近该查询执行计划中的任何地方。参数分别收到,并由数据库服务器以完全安全的方式处理,是由为living living 的人编写的。。
无论您尝试多么努力,您或任何人都可以提出任何卫生化。
如果用户输入是可执行的SQL语句的一部分,则不安全。
不要假装完成服务器的工作。只是不要。
做对了。
学习使用ADODB Command
和Parameter
对象。它们具有相当简单的API,并且正确,始终如一地使用它们将击败任何字符串征用式伪造的SQL字符串。
这是一个冗长的示例:
Const sql As String = "SELECT Id FROM dbo.Users WHERE UserName = ?;"
Dim conn As ADODB.Connection
Set conn = New ADODB.Connection
conn.ConnectionString = "{connection string}"
conn.Open
Dim cmd As ADODB.Command
Set cmd = New ADODB.Command
cmd.CommandType = adCommandText
cmd.CommandText = sql
cmd.ActiveConnection = conn
Dim userNameParam As ADODB.Parameter
Set userNameParam = New ADODB.Parameter
userNameParam.Type = adVarChar
userNameParam.Size = 60
userNameParam.Direction = adParamInput
userNameParam.Value = pUserName '<~ user input
cmd.Parameters.Append userNameParam
Dim result As ADODB.Recordset
Set result = cmd.Execute
MsgBox result("Id").Value
conn.Close
我说冗长,因为当您明确指定所有内容时,这就是您的操作方式。就我个人而言,我使用自己的ADODB包装类,与他们一起使用此代码完全等同于上述内容:
Const sql As String = "SELECT Id FROM dbo.Users WHERE UserName = ?;"
Dim result As Long
result = SqlCommand.QuickSelectSingleValue(sql, pUserName)
MsgBox result
,您可以看到,使用适当的面向对象的代码,可以为您封装所有管道,向数据库服务器发送适当的参数化且完全安全的查询。
这是:
- 在苍蝇上创建ADODB参数
- 实现任何ADODB查询
这些类,具有固定的一些错误和其他功能,可以在VBEX存储库中的GitHub上找到,该库还恰好包含许多其他有用工具的卡车(在GPLV3下许可)。请注意,虽然我确实撰写了一些代码或一些启发那里的代码,但我没有声称与VBEX存储库有任何隶属关系。i did 将这些类的原始版本上传到我自己的vbtools存储库,并在CC-BY-SA下许可,任何堆栈交换内容也是如此。