1

我之前发布了一个关于邮件合并操作的问题,我将参数直接添加到邮件合并中:

sqlstatement:="SELECT * FROM [Customer Data] 
WHERE [Customer Data].[Status]='Complete' 
AND [Customer Data].[CompletedBy] = '" & userID & "' 
AND [Customer Data].[Date Completed] Between #" & date1 & "# 
And #" & date2 & "#;"

将 SQL 选择查询更改为 VBA

评论中建议这是一个坏主意;我知道数据库操作应该避免这种情况,因为可以利用它来运行更改数据库的代码,但是对于打印邮件合并来说这是一个坏主意吗?这会导致现实世界的漏洞利用吗?似乎 SQL 只选择将填充到字母合并上的内容。为了正确填充邮件合并,还有哪些其他选项可用?

Set objword = GetObject("S:\Share with Bob\Administration 2010 Repository\Mail Merge\AIB.doc")
'Make Word visible
objword.Application.Visible = True
'Set the mail merge data source to the database
objword.MailMerge.OpenDataSource _
        Name:="C:\Database.mdb", _
        LinkToSource:=True, _
        Connection:="[TABLE - TRANSACTION]", _
        sqlstatement:="SELECT * FROM [TABLE - TRANSACTION] ORDER BY [TABLE - TRANSACTION].[Transaction Number]"
'Execute the mail merge
objword.MailMerge.Destination = wdSendToNewDocument
objword.MailMerge.Execute
objword.Application.Options.PrintBackground = False
'Print a copy
objword.Application.ActiveDocument.PrintOut
'Close Word and do not save the changes
objword.Application.Quit SaveChanges:=wdDoNotSaveChanges
'Clear the objWord Object
Set objword = Nothing
4

2 回答 2

0

您问题中的特定语句可能不是特别容易受到 SQL 注入的影响,但您对上一个问题的评论可能试图说服(或提醒)您“将这样的 SQL 语句“粘合在一起”是您应该尝试的不良习惯™很难打破。如果您养成使用参数化查询(或记录集更新,或其他更安全的替代方案)的良好习惯™,那么您在编写代码时系统地消除了潜在的利用向量(或只是潜在的故障点)。

除非你住在乡下,否则你很可能习惯在离开时锁上你的房子。您可能不会在每次外出时停下来评估房屋被闯入的可能性,您只需锁上门即可。良好的编码习惯是这样的:您只需这样做,您的应用程序就会变得更好(即更安全和更可靠)。

编辑回复:评论

对于这种特殊情况,创建临时表是为 Word 提供合并数据源的完全可接受的方式。我会假设...

  1. Access 应用程序被拆分为一个前端数据库文件(带有查询、表单、报告和宏/模块代码),该文件使用链接表来更新后端数据库文件(带有共享的持久表),以及

  2. 每个用户在本地硬盘上都有自己的前端文件副本(指向网络上共享的后端文件)

...因为这对于成功部署多用户 Access 应用程序是绝对必要的。

在这种情况下,在前端文件中创建临时表应该不会在不同用户之间造成任何问题,因为每个用户都有自己的前端文件副本,因此它们之间不会发生冲突。

创建本地临时表的代码如下所示:

Dim qdf As DAO.QueryDef
Set qdf = CurrentDb.CreateQueryDef("", _
        "PARAMETERS prmUserID Text ( 255 ), prmDate1 DateTime, prmDate2 DateTime; " & _
        "SELECT [Customer Data].* INTO temp_tbl_forWordMerge " & _
        "FROM [Customer Data] " & _
        "WHERE ((([Customer Data].Status)='completed') " & _
            "AND (([Customer Data].CompletedBy)=[prmUserID]) " & _
            "AND (([Customer Data].[Date Completed]) Between [prmDate1] And [prmDate2]))")
qdf!prmUserID = "user1"                 '' actually these values would come
qdf!prmDate1 = DateSerial(2013, 6, 10)  ''   from controls on a form where the
qdf!prmDate2 = DateSerial(2013, 6, 20)  ''     user can specify the values they want
qdf.Execute
Set qdf = Nothing

然后,当您将细节传递给 Word 时,您可以使用类似这样的内容

objword.MailMerge.OpenDataSource _
        Name := Application.CurrentProject.FullName, _
        LinkToSource := True, _
        Connection := "[temp_tbl_forWordMerge]", _
        sqlstatement := "SELECT * FROM [temp_tbl_forWordMerge] ORDER BY [Transaction Number]"

...Application.CurrentProject.FullName在 Access VBA 中的位置返回执行代码的前端文件的完全限定路径(以及临时表所在的位置)。

于 2013-06-06T13:43:52.647 回答
0

Access 数据库通常不会暴露给 Internet 或真正的恶意用户。因此,没有开发很多工具来防止 SQL 注入。

如果您认为您的应用程序易受攻击,则此声明可以建议一个简单的修复方法。它可能不是所有情况下的防弹,但对你来说就足够了。

对于非字符类型,您可以将变量转换为其类型。因此将恶意字符串转换为整数会导致错误。

sqlstatement:="SELECT * FROM [Customer Data] WHERE [Customer Data].[Status]='Complete' AND [Customer Data].[CompletedBy] = '" & cast (cast (userID as int) as varchar (50) )& "' AND [Customer Data].[Date Completed] Between #" & cast ( cast ( date1 as date) as varchar (12)) & "# And #" & cast ( cast ( date2 as date) as varchar ( 12)) & "#;"

于 2013-06-06T11:58:46.320 回答