【问题标题】:Microsoft Access SQL InjectionMicrosoft Access SQL 注入
【发布时间】:2013-06-19 03:25:42
【问题描述】:

我需要解决我们被指派维护的非 IT 应用中的一些安全问题。它位于 Microsoft Access 前端(SQL Server 后端)中。

有谁知道 SQL 注入是否可以通过 Microsoft Access 控件的 RecordSource 或 RowSource 属性来完成?例如,如果我将列表框的记录源设置为

Me.SomeListBox.Recordsource = 'SELECT * FROM SomeTable WHERE SomeField = ''' & Me.txtSomeTextBox & '''.

我不确定微软是否为这些属性内置了预防功能,所以我想知道我是否应该通过清理功能运行 Me.txtSomeTextBox。

这当然是一个快速的解决方案...该应用程序将在今年晚些时候重新设计并从 Access 迁移(耶!)。

提前谢谢各位!

【问题讨论】:

  • 我的建议:在今年晚些时候,当 Access 前端退役(“耶!”)并且问题自行消失。
  • 它易受攻击,将' 放入txtSomeTextBox 看看会发生什么
  • 戈德,这就是问题所在,尽管他们仍然希望完成它的一次性工作......所以我可以用来更快地将其从 Access 中取出的资源将被浪费:-(。希望我能在这里使用每个人的提示来最大程度地减少痛苦。

标签: sql vba ms-access sql-injection ms-access-2010


【解决方案1】:

可以使用 VBA 消除在 WHERE 条件中明显使用字段名称。

Sub btnLogin_OnClick()

If instr(0, me.txtBox, someFieldName) > 0 Then
        Msgbox("Foo Bar!")
Else
   Login
End If

End Sub

【讨论】:

    【解决方案2】:

    如果你在做字符串连接,你很容易受到攻击。

    【讨论】:

    • 你是对的。我们最终至少尝试通过黑名单运行任何用户文本以及创建 VBA 将调用的参数化存储过程来最小化可能性。考虑到这是一次性工作,这比我希望的要多,但至少存储过程被设计为可在重新设计应用程序中重用:-)
    【解决方案3】:

    在您的情况下,注入无法进入 sql server。通过链接表访问本地查询仅限于一个 sql 语句。因此,虽然“小”可能注入 Access 是可能的,但 sql 字符串无法作为多个 sql 语句到达 SQL 服务器,也不可能在您给定的示例中运行服务器端 SQL。

    因此,“内置预防”是此类 SQL 仅限于一个字符串。

    因为生成的字符串不能是多个sql语句,并且因为文本框结果被“引用”,所以你只能提供一个字符串表达式作为条件,并且你给定的例子不可能注入sql。

    如果有人可以根据文本框的示例 VBA sql + concat 发布一个有效的注入示例,那么我全神贯注。

    因此,虽然 Access 中可能会发生“某些”注入案例,但您的示例肯定不是我所知道的这种情况。

    知识渊博的用户可能会得到一个在该表达式中运行的 VBA() 函数,但他们必须知道实际 VBA 函数的名称。即使在这种情况下,它也不会执行一些您不想执行的 SQL。

    我想可以查看任何删除记录且值/表达式由用户提供的 sql 字符串,但您给出的示例不是典型的 sql 注入风险。

    【讨论】:

    • Access SQL 不支持使用 ot ";"分隔多个语句。并且access SQL不能执行多个用;分隔的SQL语句。所以,不,那是行不通的。 Access sql 中也没有 read_permissions=1 。因此,您的建议和示例与 Access SQL 及其工作方式的关系为零。
    • 构建 sql 字符串,通过将常量与用户输入连接将在 MS Access 中创建漏洞。我发布了一个示例作为答案。
    【解决方案4】:
    Me.SomeListBox.Recordsource = 'SELECT * FROM SomeTable WHERE SomeField = ''' & Me.txtSomeTextBox & '''
    

    你可以做一个包装,只是为了避免破坏组合的 SQL 查询 例如

    Me.SomeListBox.Recordsource = 'SELECT * FROM SomeTable WHERE SomeField = ''' & Replace(Me.txtSomeTextBox,"'","''") & '''
    

    在这种情况下,您添加成对的'符号('-->''),查询不会中断。

    【讨论】:

      【解决方案5】:

      字符串与用户输入的连接很危险!

      我设置了一个示例。使用这条 SQL:

      CREATE TABLE SomeTable (SomeField varchar(20), read_permission int)
      INSERT INTO SomeTable VALUES ('a', 1), ('b', 1), ('c', 0)
      

      还有这个 VBA 代码:

      Private Sub FilterButton_Click()
         Me.SomeListBox.RowSource = "SELECT * FROM SomeTable WHERE SomeField = '" & Me.txtSomeTextBox & "' AND read_permission = 1"
      End Sub
      

      您似乎创建了一个基于行的权限。只有带有read_permission = 1 的行才会显示在组合框中。

      但如果用户在文本框中输入' OR 1=1 OR',他突然可以查看所有数据(即使是那些带有read_permission = 0的行。

      在用户输入中将' 替换为'' 似乎会使执行sql 注入变得更加困难。我找不到任何字符串来打破它(还)。但最好的办法可能是找到另一种构建 sql 字符串的方法。

      Private Sub FilterButton_Click()
         Me.SomeListBox.RowSource = "SELECT * FROM SomeTable WHERE SomeField = '" & Replace(Me.txtSomeTextBox, "'", "''") & "' AND read_permission = 1"
      End Sub
      

      【讨论】:

      • 你不会找到一个字符串来打破它。使用的方法是古斯塔夫的CSql() function。它处理字符串和其他变量。
      • @Andre Gustav 的 CSql 函数修剪字符串,然后将空字符串转换为空值,这可能并不总是您想要的行为。
      • 在此示例中,子句将是:WHERE SomeField = OR 1=1 OR AND read_permission = 1 并且不会返回任何行.....
      【解决方案6】:

      回答您最初的问题:这取决于控件。列表框和组合框可以有一个选择查询作为它们的记录源。不是动作查询。

      文本框控件只能绑定到表格字段。

      这些控件对任何最终用户均不可用,因此他们可以在编译为 .accde 文件类型时重新定义记录源。

      【讨论】:

      • 即使只能创建selects,这也可能是个问题。列表框和组合框很容易受到攻击,如果它们的行源是用字符串连接构建的。
      猜你喜欢
      • 2013-05-21
      • 2012-09-23
      • 1970-01-01
      • 2011-03-10
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-10-14
      • 2017-09-02
      相关资源
      最近更新 更多