Eli*_*ias 0 sql-server ms-access vba pass-through
我试图将MS Access与SQL Server连接,我想确保我不容易受到SQL注入攻击.
我已经看到了使用ADO创建查询的参数化版本的建议,但我想学习如何通过DAO传递来清理我的输入.
目前我正在逃避单引号和反斜杠.
VBA中是否有任何标准的SQL Server注入卫生方法?
VBA中是否有任何标准的SQL Server注入卫生方法?
不.如果有的话,我会非常担心.我不做PHP,但我读过关于它的"标准SQL注入卫生方法"的恐怖故事.只是看看用PHP和sql标记的Code Review问题- 很多人都在问"这个代码是否安全?"的变体,除非他们使用预备语句,否则答案总是"不".
');--DROP TABLE Users;--
在UserName
数据库字段中看到的是一个相当值得怀疑的值(你认为这个答案的文本存储在哪里?),但是如果你已经正确编写了数据访问代码,那么就没有理由引起任何混乱,即使您的登录被授权(服务器端)执行此类声明.
问题不在于用户的输入.问题是将用户输入连接成可执行SQL,从而将用户输入视为可执行代码.
你想要的是执行一个常量的 SQL语句.当你这样做:
' *** DON'T DO THIS ***
Dim sql As String
sql = "SELECT Id FROM dbo.Users WHERE UserName = '" & pName & "';"
Run Code Online (Sandbox Code Playgroud)
然后每次将SQL语句发送到服务器时,它都是一个不同的查询:服务器甚至不知道涉及参数,它看到的只是:
SELECT Id FROM dbo.Users WHERE UserName = ''');--DROP TABLE Users;--';
Run Code Online (Sandbox Code Playgroud)
注意额外的单引号; 如果你正在考虑嘿,SQL注入被阻止,你忘记了这不是因为你不能打败你的输入清理,那是NOBODY可以.很多公司都有使用这种"注入预防"的面向世界的网站,并认为他们的代码是安全的.当他们在推特上吹嘘他们"十多年来一直没有被黑客入侵"时,全球各地的剧本小孩需要几分钟时间才能将其删除.不能费心去挖掘链接,但这个确切的故事发生了,而不是最近.
当您通过ADO发送参数化查询时,这是服务器收到的内容:
SELECT Id FROM dbo.Users WHERE UserName = ?;
Run Code Online (Sandbox Code Playgroud)
请注意,查询不知道甚至不需要关心参数的类型及其周围的单引号.
请注意,无论用户输入是什么,它都是相同的相同语句.
请注意,参数值甚至不会涉及该查询的执行计划中的任何位置.参数是单独接收的,并由数据库服务器以完全安全的方式处理,由以此为生的人编写.
无论你怎么努力,都没有任何人可以提出的消毒方法.
如果用户输入是可执行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
Run Code Online (Sandbox Code Playgroud)
我说详细,因为当你明确指定一切时,你就是这样做的.就个人而言,我使用自己的ADODB包装类,并且使用它们,这段代码完全等同于上面的内容:
Const sql As String = "SELECT Id FROM dbo.Users WHERE UserName = ?;"
Dim result As Long
result = SqlCommand.QuickSelectSingleValue(sql, pUserName)
MsgBox result
Run Code Online (Sandbox Code Playgroud)
正如您所看到的,使用适当的面向对象的代码来封装所有管道,向数据库服务器发送正确参数化且完全安全的查询并不难.
这是如何做:
修复了一些错误和其他功能的类可以在VBEX存储库的GitHub上找到,它也恰好包含一大堆其他有用的工具(根据GPLv3许可).请注意,虽然我确实编写了一些代码,或者一些启发了那些内容的代码,但我并没有声称与VBEX存储库有任何关联.我确实将这些类的原始版本上传到我自己的VBTools存储库,但是在CC-by-SA下获得许可,就像任何Stack Exchange内容一样.
归档时间: |
|
查看次数: |
322 次 |
最近记录: |