【问题标题】:How to sanitize all variables passed to the selectionArgs array?如何清理传递给 selectionArgs 数组的所有变量?
【发布时间】:2017-05-19 18:49:07
【问题描述】:

Veracode 静态扫描报告指出我的 Content Provider 实现中存在 SQL 注入缺陷。

之前,我发布了这个question,与我对这个缺陷的所有疑问有关。

经过几次讨论后,我得出结论,报告中可能存在误报。因为根据我研究和阅读的内容,我遵循 Android docsother referenced sources 中提到的安全准则以避免 SQL 注入。

到处都有建议对传递给 SQL 查询的数据执行至少一些输入验证。我想涵盖这种可能性,这是缺陷的原因。 每个人都要求我在传递给查询之前清理数据。 如何准确清理传递给 selectionArgs 数组的变量,这些变量传递给 Content Provider 的 delete()、update() 方法?

DatabaseUtils.sqlEscapeString() 就足够了吗? 请推荐!

这是我需要清理变量的实现:

 public Loader<Cursor> onCreateLoader(int id, Bundle b) {
    switch (id) {
        case THOUGHT_LOADER:
            return new CursorLoader(getActivity(), NewsFeedTable.CONTENT_URI, NewsFeedTable.PROJECTION, NewsFeedTable._id + "=?", new String[]{tid}, null);
        case COMMENT_LOADER:
            return new CursorLoader(getActivity(), CommentTable.CONTENT_URI, CommentTable.PROJECTION, CommentTable.COLUMN_TID + "=?", new String[]{tid}, null);
        default:
            return null;
    }
}

报告指出了缺陷:SQL 命令中使用的特殊元素的不正确中和(“SQL 注入”)(CWEID 89) 在这一行

deleted = db.delete(BulletinTable.TABLE_NAME, selection, selectionArgs); 在下面的代码中:

 @Override
public int delete(Uri uri, String selection, String[] selectionArgs) {
    if (uri.equals(Contract.BASE_CONTENT_URI)) {
        deleteDatabase();
        return 1;
    }

    SQLiteDatabase db = openHelper.getWritableDatabase();

    int deleted = 0;
    switch (matcher.match(uri)) {
        case BULLETIN:
            deleted = db.delete(BulletinTable.TABLE_NAME, selection, selectionArgs);
            break;
        case CLASSROOMS:
            deleted = db.delete(ClassroomsTable.TABLE_NAME, selection, selectionArgs);
            break;
        default:
            throw new IllegalArgumentException("Unsupported URI: " + uri);
    }

    if (deleted > 0) {
        getContext().getContentResolver().notifyChange(uri, null);
    }

    return deleted;
}

【问题讨论】:

  • @CL ,我添加了代码 sn-p 报告指出问题中的缺陷。它不会抱怨任何特定值,而是仅提供代码中检测到此缺陷的行号以及有关该缺陷的详细信息和一些建议。它是 Content Provider 实现的 delete() 方法。我已删除图像并在其位置添加了代码。
  • 这两段代码有什么关系? delete 在哪里调用?为什么这不是您之前问题的重复?
  • 是的,这是两段不同的代码。他们不必彼此做任何事情。第一个代码 sn-p:显示实现我如何在 selectionArgs 数组中传递变量。 第二个代码 sn-p:检测到缺陷的点。标记为重复:可能这个问题可以被认为是重复的。但我试图回答我的另一个关于清理数据的问题。所以,我想创建一个不同的问题。

标签: android sqlite android-contentprovider sql-injection veracode


【解决方案1】:

selectionArgs 数组中的值永远不需要清理,因为它们不能被解释为 SQL 命令(这就是拥有单独参数值的全部意义所在)。

sqlEscapeString() 的目的是格式化字符串,以便可以将其放入 SQL 命令中(即,转义单引号;所有其他字符在 SQL 字符串中没有意义)。但是当你知道有字符串时,你应该改为selectionArgs,所以这个函数没有帮助。

您只需要清理以 SQL 命令本身结尾的字符串。在这种情况下,这将是selection。如果此值来自用户或其他应用程序,则您无法控制 DELETE 语句实际执行的操作(它可以调用 SQL 函数,或执行访问数据库其他部分的子查询)。

出于实际目的,无法清理旨在包含 SQL 命令的字符串,因为这样您就需要一个完整的 SQL 解析器。如果您的内容提供程序可用于外部代码,您应该只允许通过 URI 删除特定项目,并且不允许自定义 selections。

【讨论】:

    猜你喜欢
    • 2011-06-27
    • 2011-11-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-09-29
    • 2019-08-18
    • 1970-01-01
    • 2011-09-18
    相关资源
    最近更新 更多