【问题标题】:Android SQLite - replace part of a string safelyAndroid SQLite - 安全地替换字符串的一部分
【发布时间】:2019-07-24 14:57:59
【问题描述】:

我需要重命名数据库中任务标题中的标签。 我看到类似的问题like this one 但在我的应用程序中,用户可以创建具有自定义标题的任务。因此,以下解决方案可能很危险:

db.execSQL("UPDATE " + Task.TABLE +
            " SET title = REPLACE(title, '" + fromTagName + "', '" + toTagName + "');");

如果用户将在标题中创建带有一些危险命令的任务(注入)怎么办?这种方法会崩溃吗?是否可以使用特殊的 android 方法代替原始 SQL 命令?还是这样安全?

【问题讨论】:

    标签: java android sqlite android-sqlite


    【解决方案1】:

    您可以将update() 方法与ContentValues() 一起使用:

    ContentValues cv = new ContentValues();
    cv.put("title", "new value");
    int rows = db.update(Task.TABLE, cv, "id = ?", new String[] {String.valueOf(yourid)})
    

    3d 参数是更新语句的WHERE 子句,? 是一个占位符,您需要在第四个参数中为其提供一个值。
    所以该语句等价于:

    UPDATE <Task.TABLE> SET title = 'new value' WHERE id = <yourid> 
    

    在变量rows 中,方法update() 返回更新的行数。
    这个方法是sql-injection 安全的。

    【讨论】:

    • 在您的示例中,我需要知道新值以替换旧值。但在我的情况下,新值是通过替换字符串基于旧值构建的。所以我不明白我怎么能在我的情况下使用它。只能查询游标,在java代码中处理数据,然后使用db.update来更新数据库,但是太过分了。
    • 这太过分了,但你的问题是关于安全的,对吧?你必须决定你喜欢什么。
    【解决方案2】:

    使用绑定变量。只需放置一个 ?你有一个变量,并按顺序将一个参数数组传递给 rawQuery 函数。

    永远不要像上面那样使用串联。到处使用绑定变量。任何用户输入都应该在绑定变量中,任何常量都应该在查询中。这消除了所有可能的 SQL 注入。

    【讨论】:

    • db.execSQL("UPDATE" + Task.TABLE +" title = REPLACE(title, '?', '?');", new Object[]{fromTagName, toTagName});像这样?
    • @OleksandrAlbul 对于 execSql() 的这种重载,文档:developer.android.com/reference/android/database/sqlite/… 很清楚:执行不是 SELECT/INSERT/UPDATE/DELETE 的单个 SQL 语句
    • @OleksandrAlbul 我的错,正如forpas所说,你不能使用 execSQL 进行查询,你需要使用 rawQuery() 。但是参数和格式是一样的
    • @GabeSechan 这不是查询,而是 UPDATE 语句。谢谢我已经用绑定参数重写了它。
    • @OleksandrAlbul 更新是一个查询。查询是对数据库的任何影响或查找数据的命令。
    【解决方案3】:

    使用DatabaseUtils.sqlEscapeString(stringToEscape) 在插入数据库之前清理用户输入。参考here

    【讨论】:

    • 其他人已经钻了我的心,仅仅转义字符串是不够的,并且总是使用准备好的语句和/或参数化查询。当然,如果它是第 3 方代码(不是 DBMS 的原生代码),这只是一个信任问题,但质疑此类通用方法的关键在于它们是否完全正确地转义了 特定 DBMS 的字符串.它是否正确处理替代字符串分隔符?多字节字符呢?等等。
    • 很容易错过其中之一,或者忘记正确取消转义。请改用绑定变量。
    • @CPerkins 实际上,更好的短语应该是“参考”而不是“阅读更多”谢谢
    猜你喜欢
    • 2012-05-18
    • 1970-01-01
    • 2013-08-25
    • 2022-07-18
    • 2011-08-10
    • 2017-04-23
    • 2017-09-19
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多