简体   繁体   中英

How to secure an ADO connection in an Excel VBA project?

I have an Excel spreadsheet (.xlsb) that connects to an SQL Server via ActiveX Data Objects (ADO) in VBA that I have to share with a bunch of people. The code uses the following string to connect do the database:

' Create the connection string.
sConnString = "Provider=SQLOLEDB;" & _
              "Data Source={server name};" & _
              "Initial Catalog={database name};" & _
              "UserId={username};" & _
              "Password={password};"

How do I keep my SQL username and password secure and prevent 3rd parties from gaining access to them? Is password-protecting the VBA project enough or can that be easily cracked?

VBA password protection can't be considered secure as it's easily circumvented.

You could of course add some kind of obfuscation (hash function or similar) in the VBA Code, so that the password isn't visible in plain-text, but anyone familiar with VBA should be able to get around this in little time.

I'd consider restricting the access to the db with a view that only contains the needed data.

Hiding the password could be done by putting the connection functionality in a dll, which you then reference in the VBA code. This would require more work to reverse and gives you much more possibilities to really hide the credentials. See also this reply: https://stackoverflow.com/a/19163256/5970009

VBA project is not protected enough - anyone with 2 hours free time and internet can probably go through.

What is the base case scenario is to make different users on DB level with different permissions. Then ask your users on the Excel spreadsheet to give password and username in one of the cells or through userform. Take the password and username and use it in the connection string.

As a further step to security, you may use a little small trick, that I call salting . Eg Let's say that your password for a the given user is vityata . Then ask the user to enter it. Upon entering, take the password and change it to something else. This something else should be the password to the database. I mean something like this:

Public Function str_generator(ByVal str_value As String, ByVal b_fix As Boolean) As String

    Dim l_counter As Long
    Dim l_number As Long
    Dim str_char As String

    On Error GoTo str_generator_Error

    If b_fix Then
        str_value = Left(str_value, Len(str_value) - 1)
        str_value = Right(str_value, Len(str_value) - 1)
    End If

    For l_counter = 1 To Len(str_value)
        str_char = Mid(str_value, l_counter, 1)
        If b_is_odd(l_counter) Then
            l_number = Asc(str_char) + IIf(b_fix, -2, 2)
        Else
            l_number = Asc(str_char) + IIf(b_fix, -3, 3)
        End If

        str_generator = str_generator + Chr(l_number)

    Next l_counter

    If Not b_fix Then
        str_generator = Chr(l_number) & str_generator & Chr(l_number)
    End If

    On Error GoTo 0
    Exit Function

str_generator_Error:

    MsgBox "Error " & Err.Number & " (" & Err.Description & ") in procedure str_generator of Function Modul1"

End Function

Private Function b_is_odd(l_number As Long) As Boolean

    b_is_odd = l_number Mod 2

End Function

Let's say that the user password is vityata . Then after the user enters it, it is changed to cxlv|cwcc , which is the real password for the database.

?str_generator("vityata",false)
cxlv|cwcc
?str_generator("cxlv|cwcc",true)
vityata

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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