M MathiasM Active Member Licensed User Jun 24, 2021 #1 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: Copy 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: Copy 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!
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: Copy 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: Copy 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 Jun 24, 2021 #2 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
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.
tchart Well-Known Member Licensed User Longtime User Jun 24, 2021 #3 Also watch this video, very interesting what can be achieved. Upvote 0
Erel B4X founder Staff member Licensed User Longtime User Jun 24, 2021 #4 MathiasM said: How can I safely escape the string "Username" to be used in a WHERE clause and then pass it without SQL injection possibility? Click to expand... Code: Copy Dim AllowedColumns As B4XSet = B4XCollections.CreateSet2(Array("Username", "SomeotherField", "AndAnother")) If AllowedColumns.Contains(UserInput) = False Then 'reject query End If Upvote 0
MathiasM said: How can I safely escape the string "Username" to be used in a WHERE clause and then pass it without SQL injection possibility? Click to expand... Code: Copy Dim AllowedColumns As B4XSet = B4XCollections.CreateSet2(Array("Username", "SomeotherField", "AndAnother")) If AllowedColumns.Contains(UserInput) = False Then 'reject query End If
LucaMs Expert Licensed User Longtime User Jun 24, 2021 #5 Erel said: Code: Copy Dim AllowedColumns As B4XSet = B4XCollections.CreateSet2(Array("Username", "SomeotherField", "AndAnother")) If AllowedColumns.Contains(UserInput) = False Then 'reject query End If Click to expand... I would have used a List because... I fell behind ?? Upvote 0
Erel said: Code: Copy Dim AllowedColumns As B4XSet = B4XCollections.CreateSet2(Array("Username", "SomeotherField", "AndAnother")) If AllowedColumns.Contains(UserInput) = False Then 'reject query End If Click to expand... I would have used a List because... I fell behind ??
Erel B4X founder Staff member Licensed User Longtime User Jun 24, 2021 #6 Assuming that there aren't many items then a List will work just as fine (but it is a bit less elegant). Upvote 0
Assuming that there aren't many items then a List will work just as fine (but it is a bit less elegant).
LucaMs Expert Licensed User Longtime User Jun 24, 2021 #7 Erel said: (but it is a bit less elegant) Click to expand... It would be less modern Upvote 0
M MathiasM Active Member Licensed User Jun 24, 2021 #8 Erel said: Code: Copy Dim AllowedColumns As B4XSet = B4XCollections.CreateSet2(Array("Username", "SomeotherField", "AndAnother")) If AllowedColumns.Contains(UserInput) = False Then 'reject query End If Click to expand... Simple, yet elegant. This is the way I'm going to fix it! Thanks. Upvote 0
Erel said: Code: Copy Dim AllowedColumns As B4XSet = B4XCollections.CreateSet2(Array("Username", "SomeotherField", "AndAnother")) If AllowedColumns.Contains(UserInput) = False Then 'reject query End If Click to expand... Simple, yet elegant. This is the way I'm going to fix it! Thanks.
Erel B4X founder Staff member Licensed User Longtime User Jun 24, 2021 #9 Better to lowercase the names in the B4XSet and test UserInput.ToLowerCase. Upvote 0