我之前发布了一个关于邮件合并操作的问题,我将该参数直接添加到邮件合并中:
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
答案 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提供合并数据源的完全可接受的方式。我会假设......
将Access应用程序拆分为前端数据库文件(包含查询,表单,报告和宏/模块代码),该文件使用链接表更新 -end 数据库文件(带有共享持久表)和
每个用户在其本地硬盘上都有自己的前端文件副本(指向网络上的共享后端文件)
...因为绝对必要用于成功部署多用户访问应用程序。
在这种情况下,在前端文件中创建临时表不应该导致不同用户之间出现任何问题,因为每个用户都有自己的前端文件副本,因此不能冲突彼此。
创建本地临时表的代码如下所示:
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
返回执行代码的前端文件的完全限定路径(临时表所在的位置)。