【问题标题】:android: how do I replace SQLite execSQL() to avoid injection attack?android:如何替换 SQLite execSQL() 以避免注入攻击?
【发布时间】:2018-11-19 04:18:06
【问题描述】:

我的 MainActivity resetSortIndexes 中有一个方法,它在运行 SQLite 数据库“execSQL()”方法的模型类中运行 save()。现在我读到我不应该使用 execSQL() 来避免 SQL 注入攻击,并且我不应该使用 rawQuery() 进行任何 INSERT 操作。那么我应该使用 ContentValues() 和 insert() 吗?

MainActivity.java
...
public static void resetSortIndexes() {

    int index = allList.size();
    for (ListItem s : allList) {
        s.setSortorder(index);
        s.save(sqLiteDB); 
        index--;
    }
}   

ListItem.java
...
public void save(SQLiteDB helper){

    String sql = "INSERT OR REPLACE INTO " + TABLE_NAME + "(_id,type,typecolor,todo,note1,note2," +
            "duedatentime,timestamp,notiftime,notiftime2,randint,sortorder,listone,listtwo," +
            "listthree,listfour,listfive,listsix,listseven,listeight,listnine,listten,listeleven," +
            "listtwelve,listthirteen,listfourteen,listfifteen,listsixteen,listseventeen," +
            "listeighteen,listnineteen,listtwenty) VALUES" +
            "(?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)";
    // The object parameters from the ListItem class.
    Object[] params = new Object[]{_id,_type,_typecolor,_todo,_note1,_note2,_duedatentime,
            _timestamp,_notiftime,_notiftime2,_randint,_sortorder,_listone,_listtwo,
            _listthree,_listfour,_listfive,_listsix,_listseven,_listeight,_listnine,
            _listten,_listeleven,_listtwelve,_listthirteen,_listfourteen,_listfifteen,
            _listsixteen,_listseventeen,_listeighteen,_listnineteen,_listtwenty};
    // A method in the SQLiteDB class.
    helper.executeQuery(sql,params);
}

SQLiteDB.java
...
public void executeQuery(String sql, Object[] params) {

    SQLiteDatabase db = getReadableDatabase();

    db.beginTransaction();
    try {
        **db.execSQL(sql, params);**

    db.setTransactionSuccessful();
    } finally {
        db.endTransaction();
    }
    if(db.isOpen()) {
        db.close();
    }
} 

【问题讨论】:

    标签: android android-sqlite


    【解决方案1】:

    可以使用insertWithOnConflict(TABLE_NAME,null,contentvalues,SQLiteDatabase.CONFLICT_REPLACE);的方法

    contenvalues 是使用 put(column_name,value) 方法填充每个要插入的值的 ContenValues。

    代码如下:-

    ContentValues cv = new Contentvalues();
    cv.put("_id",the_id);
    cv.put("type",the_type);
    ..... etc
    long result =  helper.insertWithOnConflict(TABLE_NAME,null,cv,SQliteDatabase.CONFLICT_REPLACE);
    
    • result 将是插入行的 rowid 或 -1。

    insertWithOnConflict

    CONFLICT_REPLACE

    附:像您一样使用 execSQL 可以防止 SQL 注入,因为 SQL 本身不受用户输入的影响,并且值被绑定/作为参数传递。

    【讨论】:

    • 好的,试一试。使用 insertWithOnConflict 而不是 insert() 有什么好处?
    • 您是否仍建议将 execSQL() 替换为 ContentValues 代码?
    • 它将执行 INSERT OR REPLACE(或处理 CONFLICT(不是外键冲突)),而不是像 insert 那样仅 INSERT OR IGNORE。
    • 嗯,我不一定会推荐。并不是说一道闪电会从天而降,把你击倒。就我个人而言,我会使用方便的方法(不是 execSQL/rawQuery),主要是因为一旦你了解了它们的要点,它们通常更容易编码。但是,有时您必须这样做,因为它们确实有一些限制。
    • 哈,我也想避开闪电。回答赞成并接受。干杯。
    猜你喜欢
    • 2011-01-13
    • 1970-01-01
    • 2011-09-15
    • 2015-11-30
    • 1970-01-01
    • 2010-09-23
    • 2013-08-09
    • 1970-01-01
    相关资源
    最近更新 更多