访问邮件合并:安全隐患

时间:2013-06-04 00:25:56

标签: sql ms-access

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

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

Changing SQL select query to 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

2 个答案:

答案 0 :(得分:0)

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

如果您认为您的应用程序是可以破坏的,那么对于此声明可以建议一个简单的解决方案。对于所有情况,它可能不是防弹,但应该足够你。

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

sqlstatement:=“SELECT * FROM [Customer Data] 在哪里[客户数据]。[状态] ='完成' AND [Customer Data]。[CompletedBy] ='“& cast(cast(userID as int)as varchar(50))&”' AND [客户数据]。[完成日期]介于#“& cast(cast(date1 as date)as varchar(12))&”# 并且#“& cast(cast(date2 as date)as varchar(12))&”#;“

答案 1 :(得分:0)

你问题中的特定陈述可能不会特别容易受到SQL注入攻击,但对你之前的问题的评论可能试图说服(或提醒)你“粘合”这样的SQL语句是坏Habit™,你应该努力打破。如果您在可能的情况下开发使用参数化查询(或记录集更新或其他更安全的替代方案)的Good Habit™,则在编写代码时系统地消除潜在的漏洞利用向量(或仅潜在的失败点)。

除非你在国内生活 WAY ,否则当你离开时,你可能习惯于锁住你的房子。您可能不会停下来评估每次外出时房屋被闯入的可能性,您只需锁上门即可。好的编码习惯是这样的:你只是它们,你的应用程序更好(即更安全,更可靠)。

编辑重新评论

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

  1. 将Access应用程序拆分为前端数据库文件(包含查询,表单,报告和宏/模块代码),该文件使用链接表更新 -end 数据库文件(带有共享持久表)和

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

  3. ...因为绝对必要用于成功部署多用户访问应用程序。

    在这种情况下,在前端文件中创建临时表不应该导致不同用户之间出现任何问题,因为每个用户都有自己的前端文件副本,因此不能冲突彼此。

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

    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]"
    

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