2017-02-20 51 views
0

我試圖將StringArrayList插入到sqlite數據庫的表中。如何通過VALUES在循環中防止sql注入

我寫了一個循環,將StringArrayList添加到使用android.database.sqlite.SQLiteOpenHelper的sqlite數據庫查詢中。

查詢對於sql注入很脆弱,並且不是最優的。我發現這些鏈接 using PreparedStatement,using SQLiteStatement。我還沒有找到在這樣的循環中防止sql注入的例子。爲了演示,我已經在示例中將ArrayList的初始化。

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) + ")"; 
    } 
} 

什麼將是最安全的解決方案的的ArrayListString S或Object s到SQLite數據庫添加?

+0

http://stackoverflow.com/a/34619804/5018798 –

+0

@GavinHarris我明白,如果我插入一行,它將如何工作。這就是我的文章中的兩個超鏈接和你的文章中的超鏈接。我寧願不要爲我插入的每一行執行單獨的插入語句。我寧願將所有要插入「VALUES」子句的行都放入。 – Janneman96

+0

這個答案有幫助嗎?實際上,您可以創建任何用戶可以輸入綁定參數的內容。你可以構造你的SQL來接受'n'個參數,你只需要跟蹤參數的數量並在execSQL上傳入正確的數字。 –

回答

1

嘗試使用SQLiteStatement,像下面:

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(); 

我承擔的id是一個字符串,所以我可以用statement.bindAllArgsAsStrings方法將變量綁定到語句。 (對不起,我也改寫你的字符串使用的String.format,我覺得更容易閱讀,如果你願意的話可以無視)

OLD答:

看看使用綁定變量。重寫你的SQL,以便在你接受用戶輸入的任何地方輸入「?」然後用db.execSQL(sqlString, Arguments);

所以,你要的SQL看起來像(在執行前):

INSERT INTO <tableName> (<key_id>, <key_description>) 
VALUES (?, ?), (?, ?), ... 

然後,您將需要壓扁你的ArrayList與任何id是穿插一個對象數組!

+0

根據'execSQL'的文檔(https://developer.android.com /reference/android/database/sqlite/SQLiteDatabase.html#execSQL(java.lang.String,%20java.lang.Object []))你可以/ t /不應該用'execSQL()'執行INSERT查詢。你是指'android.database.sqlite.SQLiteDatabase.execSQL()'或其他一些API? – mhawke

+0

你說得對,我回答得太快了。我將在AM中編輯答案。 –