1

I need to fix some security issues in a non-IT app that we were assigned to maintain. It's in Microsoft Access front-end (SQL Server back-end).

Does anyone know if SQL Injection can be done via the RecordSource or RowSource property of Microsoft Access controls? 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.

This is of course a quick fix... the application is going to be redesigned and migrated out of Access (yay!) later this year.

Thanks in advance guys!

StoneJedi
  • 575
  • 1
  • 8
  • 19
  • 1
    My recommendation: Drag your feet on this until later in the year when the Access front-end is retired ("yay!") and the issue goes away on its own. – Gord Thompson Jun 21 '13 at 22:10
  • Its vulnerable, put `'` into txtSomeTextBox and see what happens – Alex K. Jun 22 '13 at 11:34
  • Gord, that's the problem, even though its throwaway work they still want it done... So resources I could use on getting it out of Access faster will instead be wasted :-(. Hopefully I can use everyone's tips here to minimize the pain. – StoneJedi Jun 24 '13 at 00:43
  • Possible duplicate of [How do I use parameters in VBA in the different contexts in Microsoft Access?](https://stackoverflow.com/questions/49509615/how-do-i-use-parameters-in-vba-in-the-different-contexts-in-microsoft-access) – Zev Spitz Oct 12 '18 at 09:17

6 Answers6

2

Could use VBA to eliminate the obvious use of the field name in the WHERE condition.

Sub btnLogin_OnClick()

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

End Sub
dennythecoder
  • 752
  • 4
  • 15
2

In your case, the inject can NOT make it to sql server. Access local queries via a linked table are LIMITED to ONE sql statement. 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.

So the “built in prevention” is that such SQL is limited to the one string.

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.

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.

So while “some” cases of injection can occur in Access, the example you have is certainly not such a case I am aware of.

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. And even in this case, that would NOT execute some SQL you don’t want to.

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.

Albert D. Kallal
  • 42,205
  • 3
  • 34
  • 51
  • Access SQL does not support use ot ";" to separate multiple statements. And access SQL cannot execute multiple SQL statements separated by a ;. So, no, that will not work. And there is no read_permissions=1 in Access sql either. So, your suggest and examples have zero to do with Access SQL and how it works. – Albert D. Kallal Sep 23 '20 at 15:01
  • Building sql strings, by concatenating constants with user input **will create vulnerabilities** in MS Access. I posted an example as an answer. – slartidan Sep 24 '20 at 08:43
1

If you're doing string concatenation, you're vulnerable.

Joel Coehoorn
  • 399,467
  • 113
  • 570
  • 794
  • You are right. We ended up at least trying to minimize the possibilities by running any user text through a blacklist as well as creating parameterized sprocs the VBA would call instead. It was more work than I was hoping for considering it was throwaway work, but at least the sprocs are designed to be reusable in the redesign application :-) – StoneJedi Nov 09 '14 at 06:15
1
Me.SomeListBox.Recordsource = 'SELECT * FROM SomeTable WHERE SomeField = ''' & Me.txtSomeTextBox & '''

You could do a wrapper, just to avoid breaking of composed SQL query e.g.

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

In this scenario, you add paired ' symbol ('-->''), and query won't be broken.

Van Ng
  • 773
  • 1
  • 7
  • 17
1

String concatenation with user input is dangerous!

I setup an example. Use this SQL:

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

And this VBA code:

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.

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.

Example Database

Replacing ' with '' in the user input seems to make it harder to do sql injection. 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.

Private Sub FilterButton_Click()
   Me.SomeListBox.RowSource = "SELECT * FROM SomeTable WHERE SomeField = '" & Replace(Me.txtSomeTextBox, "'", "''") & "' AND read_permission = 1"
End Sub
slartidan
  • 20,403
  • 15
  • 83
  • 131
  • 1
    You won't find a string to break it. The method to use is Gustav's [`CSql()` function](https://stackoverflow.com/a/36494189/3820271) . It handles string and other variables. – Andre Sep 24 '20 at 11:00
  • @Andre Gustav's CSql function trims strings and then converts empty strings to nulls, which might not always be the behavior you want. – slartidan Sep 24 '20 at 12:17
  • in this example the clause would be: WHERE SomeField = OR 1=1 OR AND read_permission = 1 and that wouldn't return any rows..... – Cahaba Data Sep 25 '20 at 13:21
0

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.

Cahaba Data
  • 624
  • 1
  • 4
  • 4
  • Even though only `select`s can be made, this might be an issue. List Boxes and Combo Boxes are vulnerable, if their rowsource is built with string concatenation. – slartidan Sep 24 '20 at 08:46