Android 防止通过内容提供程序查询中的投影进行注入(参数化?)

Android 防止通过内容提供程序查询中的投影进行注入(参数化?),android,sqlite,Android,Sqlite,我用框架测试了一个内容提供者,结果发现query()方法中的投影容易被注入。包括“*FROM SQLITE_MASTER--”将列出所有表。防止这种情况的最好方法是什么?我添加了对某些字符的过滤: public Cursor query(Uri contentUri, String[] projection, String selection, String[] selectionArgs, String sortOrder) { /* * Filter qu

我用框架测试了一个内容提供者,结果发现
query()
方法中的投影容易被注入。包括“*FROM SQLITE_MASTER--”将列出所有表。防止这种情况的最好方法是什么?我添加了对某些字符的过滤:

public Cursor query(Uri contentUri, String[] projection, String selection, String[] selectionArgs,
        String sortOrder) {

    /*
     * Filter queries that contain certain characters to guard against SQL injection
     */
    for (String query : projection) {
        if (query.contains("*") || query.contains(";") || query.contains("'") || query.contains("\"")) {
            //Possible SQL injection attack, leave the query
            return null;
        }
    }

我知道黑名单过滤不是一个好办法,参数化投影会更好。但是,我在
query()
方法中找不到这样做的方法。它没有两个参数,比如selection有“selection”和“selectionArgs”。如何在没有黑名单的情况下最好地防止注入?

如果您想允许内容提供商的客户端使用任意复杂的SQL,那么您无能为力;像
SomeColumn这样的投影“*fromsqlite_master--;””
是完全有效且无害的。 为了防止访问敏感数据,这些数据必须位于另一个数据库中

但是,您可以施加限制,即客户端只能读取预定义的列集,而不进行更改。
要强制执行此操作,请检查
投影中的所有字符串是否等于其中一个列名。

防止投影参数中SQL注入的简单方法可能是使用
SQLiteQueryBuilder上的方法。如文件所述

如果设置了投影贴图,则它必须包含用户可能请求的所有列名,即使键和值相同

我试图通过添加此方法修复易受攻击的内容提供商,drozer向我展示了以下内容:

dz> run app.provider.query content://myContentProvider/myPath/ --projection "'"
Invalid column '

所以你会选择白名单而不是黑名单?可能:检查内容提供者名称的表名,如果投影数组中的每个字符串不等于该表的一个列名,则抛出exception?这就是我写的。或者你只是说客户端可以读取数据库中的所有内容。