简体   繁体   English

Microsoft Access SQL 注入

[英]Microsoft Access SQL Injection

I need to fix some security issues in a non-IT app that we were assigned to maintain.我需要修复分配给我们维护的非 IT 应用程序中的一些安全问题。 It's in Microsoft Access front-end (SQL Server back-end).它位于 Microsoft Access 前端(SQL Server 后端)中。

Does anyone know if SQL Injection can be done via the RecordSource or RowSource property of Microsoft Access controls?有谁知道是否可以通过 Microsoft Access 控件的 RecordSource 或 RowSource 属性完成 SQL 注入? For example, if I set a listbox's recordsource to例如,如果我将列表框的记录源设置为

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

I'm not sure if Microsoft has built in prevention or not for those properties so I'm wondering if I should be running that Me.txtSomeTextBox through a cleaning function.我不确定微软是否为这些属性内置了预防措施,所以我想知道我是否应该通过清理功能运行 Me.txtSomeTextBox。

This is of course a quick fix... the application is going to be redesigned and migrated out of Access (yay!) later this year.这当然是一个快速修复……今年晚些时候,该应用程序将重新设计并从 Access 中迁移出来(是的!)。

Thanks in advance guys!在此先感谢各位!

Could use VBA to eliminate the obvious use of the field name in the WHERE condition.可以使用 VBA 来消除 WHERE 条件中明显使用字段名称的情况。

Sub btnLogin_OnClick()

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

End Sub

如果您正在进行字符串连接,则很容易受到攻击。

In your case, the inject can NOT make it to sql server.在您的情况下,注入无法进入 sql server。 Access local queries via a linked table are LIMITED to ONE sql statement.通过链接表访问本地查询仅限于一个 sql 语句。 So while a “small” possible of injection into Access is possible, the sql string cannot reach SQL server as multiple sql statements, nor is running of server side SQL possible with your given example.因此,虽然可以将“小”注入 Access 中,但 sql 字符串无法作为多个 sql 语句到达 SQL 服务器,也无法在您给定的示例中运行服务器端 SQL。

So the “built in prevention” is that such SQL is limited to the one string.所以“内置预防”是这样的 SQL 仅限于一个字符串。

Because the resulting string cannot be multiple sql statements, and because the text box result is “quoted”, then you can ONLY supply a string expression as the condition, and it is NOT possible with your given example to inject sql.因为结果字符串不能是多个sql语句,并且因为文本框结果是“引用”的,所以你只能提供一个字符串表达式作为条件,并且你给定的例子是不可能注入sql的。

If someone can post a working example of injection based on the sample VBA sql + concat of the text box, then I am all ears.如果有人可以根据文本框的示例 VBA sql + concat 发布注入的工作示例,那么我全神贯注。

So while “some” cases of injection can occur in Access, the example you have is certainly not such a case I am aware of.因此,虽然 Access 中可能会发生“某些”注入情况,但您的示例肯定不是我所知道的这种情况。

A knowledgeable user could perhaps get a VBA() function to run in that expression, but they would have to know the name of the actual VBA function.一个知识渊博的用户也许可以得到一个 VBA() 函数在该表达式中运行,但他们必须知道实际 VBA 函数的名称。 And even in this case, that would NOT execute some SQL you don't want to.即使在这种情况下,也不会执行一些您不想执行的 SQL。

I suppose any sql string that deletes records and the value/expression is supplied by a user could be looked at, but your given example is not a typical sql injection risk.我想可以查看任何删除记录和用户提供的值/表达式的 sql 字符串,但是您给定的示例不是典型的 sql 注入风险。

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

You could do a wrapper, just to avoid breaking of composed SQL query eg你可以做一个包装器,只是为了避免破坏组合的 SQL 查询,例如

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

In this scenario, you add paired ' symbol ('-->''), and query won't be broken.在这种情况下,您添加成对的 ' 符号 ('-->''),查询不会中断。

To answer your original question: it depends on the control.回答您最初的问题:这取决于控件。 The List Box and Combo Box can have a Select Query as their record source.列表框和组合框可以有一个选择查询作为它们的记录源。 Not an action query.不是动作查询。

The Text Box control can only be bound to a table field.文本框控件只能绑定到表格字段。

These controls are not available to any end users such that they could redefine the record source when compiled to the .accde file type.任何最终用户都无法使用这些控件,以便他们在编译为 .accde 文件类型时可以重新定义记录源。

String concatenation with user input is dangerous!与用户输入的字符串连接是危险的!

I setup an example.我设置了一个例子。 Use this SQL:使用此 SQL:

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

And this VBA code:这个 VBA 代码:

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

Seemingly, you created a row based permission.看起来,您创建了一个基于行的权限。 Only rows with read_permission = 1 will be shown in the combobox.只有read_permission = 1行才会显示在组合框中。

But if the user enters ' OR 1=1 OR' in the textbox, he suddenly can see all data (even those rows with read_permission = 0 .但是如果用户在文本框中输入' OR 1=1 OR' ,他会突然看到所有数据(甚至那些read_permission = 0行。

示例数据库

Replacing ' with '' in the user input seems to make it harder to do sql injection.更换'''在用户输入似乎使它更难做SQL注入。 I could not find any string to break it (yet).我找不到任何字符串来打破它(还)。 But the best idea is probably to find another way of builing the sql string.但最好的主意可能是找到另一种构建 sql 字符串的方法。

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM