B4J Question How to avoid SQL injection in SQL without question marks?

MathiasM

Active Member
Licensed User
Hello

I have SQL queries assembled by user inputted(?) data, ofcourse I want to avoid SQL injections.
Normally I would do something like this=

SQL:
SELECT * FROM Users WHERE Username = ?

And then pass parameters to replace the "?".

But now, in this case, "Username" is also a variable passed by the user (coming from a filter query parameter in a REST api)

I tried this:

SQL:
SELECT * FROM Users WHERE ? = ?

And then passing "Username" and the the actual Username as parameters. However, the SQL class doesn't seem to support this as the resultset is closed after trying to read data out of it.

How can I safely escape the string "Username" to be used in a WHERE clause and then pass it without SQL injection possibility?

Thanks a bunch!
 

tchart

Well-Known Member
Licensed User
Longtime User
There is some good discussion on stackoverflow on this topic. The consensus was that there is no 100% way to detect it.

In one of my products I have the ability for administrators to write ad-hoc SQL queries for reporting purposes. So avoid any nasty command (delete, drop etc) I have a function that checks whether a statement is a select only statement. Again not 100% reliable but better than nothing. Happy to share this if you want.

For your problem there is also issues with selects within selects which can also leads to data leaks.
 
Upvote 0

Erel

B4X founder
Staff member
Licensed User
Longtime User
How can I safely escape the string "Username" to be used in a WHERE clause and then pass it without SQL injection possibility?

B4X:
Dim AllowedColumns As B4XSet = B4XCollections.CreateSet2(Array("Username", "SomeotherField", "AndAnother"))

If AllowedColumns.Contains(UserInput) = False Then
    'reject query
End If
 
Upvote 0

MathiasM

Active Member
Licensed User
B4X:
Dim AllowedColumns As B4XSet = B4XCollections.CreateSet2(Array("Username", "SomeotherField", "AndAnother"))

If AllowedColumns.Contains(UserInput) = False Then
    'reject query
End If

Simple, yet elegant. This is the way I'm going to fix it! Thanks.
 
Upvote 0
Top