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?这就是我写的。或者你只是说客户端可以读取数据库中的所有内容。