Reputation: 505
I'm trying to insert an ArrayList
of String
s to a table in an sqlite database.
I've written a loop that adds String
s from an ArrayList
to an sqlite database query using android.database.sqlite.SQLiteOpenHelper
.
The query is vulnerable for sql injection and is not optimal. I've found these links
using PreparedStatement, using SQLiteStatement. I haven't found examples of preventing sql injection in a loop like this. For demonstration's sake, I've put the initialization of the ArrayList
in the example.
ArrayList<String> descriptions = new ArrayList<>();
SQLiteDatabase db = this.getWritableDatabase();
String addBulkQuery = "INSERT INTO " + TABLE_DESCRIPTIONS + "(" + KEY_ID + ", " + KEY_DESCRIPTION + ") VALUES";
if (descriptions.size() > 0) {
addBulkQuery += "(" + id + ", " + descriptions.get(0) + ")";
for (int i = 1; i < descriptions.size(); i++) {
addBulkQuery += ", (" + id + ", " + descriptions.get(i) + ")";
}
}
What would be the most secure solution to add an ArrayList
of String
s or Object
s to the sqlite database?
Upvotes: 0
Views: 1668
Reputation: 702
Try using a SQLiteStatement, something like the below:
ArrayList<String> descriptions = new ArrayList<>();
ArrayList<String> bindArgs = new ArrayList<>(descriptions.size() * 2);
String values = "";
if (descriptions.size() > 0) {
values += "(?,?)";
bindArgs.add(id);
bindArgs.add(descriptions.get(0));
for (int i = 1; i < descriptions.size(); i++) {
values += ",(?,?)";
bindArgs.add(id);
bindArgs.add(descriptions.get(i));
}
}
String addBulkQuery = String.format("INSERT INTO %s (%s, %s) VALUES %s", TABLE_DESCRIPTIONS, KEY_ID, KEY_DESCRIPTION, values);
SQLiteStatement statement = db.compileStatement(addBulkQuery);
statement.bindAllArgsAsStrings( bindArgs.toArray(new String[0]) );
statement.executeInsert();
I have assumed the id
is a String and therefore I can use the statement.bindAllArgsAsStrings
method to bind the variables to the statement. (Sorry I also rewrote your Strings to use String.format, I find it easier to read, you can ignore if you like)
OLD Answer:
Look at using Bind Variables. Rewrite your SQL so that anywhere you accept user input, enter in a "?" and then use db.execSQL(sqlString, Arguments);
So you want the SQL to look like (before you execute):
INSERT INTO <tableName> (<key_id>, <key_description>)
VALUES (?, ?), (?, ?), ...
You will then need to flatten your ArrayList into an Object Array interspersed with whatever id
is!
Upvotes: 1