我有一个内容提供程序,我使用Drozer框架进行了测试,结果发现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()
方法中看到这样做的方法。它没有两个参数,比如选择"选择"那么" selectionArgs"。如何在没有黑名单的情况下防止注射?
答案 0 :(得分:0)
如果您希望允许内容提供商的客户端使用任意复杂的SQL,那么您无能为力;像SomeColumn AS "* FROM sqlite_master -- ;'"""
这样的投影将完全有效且无害。
为了防止访问敏感数据,该数据必须位于另一个数据库中。
但是,您可以施加限制,即客户端只能读取预定义的一组列,而不会更改。
要强制执行此操作,请检查projection
中的所有字符串是否等于其中一个列名。
答案 1 :(得分:0)
在投影参数中防止SQL注入的简单方法可能是在SQLiteQueryBuilder
上使用setProjectionMap方法。如文档中所述,
如果设置了投影映射,则必须包含用户可能请求的所有列名,即使键和值相同。
我试图通过添加此方法修复易受攻击的内容提供商,以下是drozer向我展示的内容:
dz> run app.provider.query content://myContentProvider/myPath/ --projection "'"
Invalid column '