gpt4 book ai didi

android - 修复 Content Provider Android 上的 SQL 注入(inject)漏洞

转载 作者:行者123 更新时间:2023-11-30 05:11:07 26 4
gpt4 key购买 nike

我有不同的应用程序彼此共享一些数据,这是通过内容提供程序完成的,但是当我上传 apk 时,我收到一封电子邮件说“您的应用程序正在使用包含 SQL 注入(inject)漏洞的内容提供程序。”

根据 Google 指南,有几种方法可以解决此问题:

如果受影响的 ContentProvider 需要暴露给其他应用:

  • 您可以使用以下方法防止 SQL 注入(inject)到 SQLiteDatabase.query 中带有投影图的严格模式。严格模式防止恶意选择条款和投影图防止恶意转换条款。您必须使用这两种功能来确保您的查询是安全的。

  • 您可以通过使用带有“?”的选择子句来防止 SQL 注入(inject)到 SQLiteDatabase.update 和 SQLiteDatabase.delete 中作为可替换参数和单独的选择参数数组。您的选择子句不应由不受信任的输入构成。

但我不清楚如何继续任何解决方案,我不知道如何使用投影图或使用使用“?”的选择子句更改代码。我的意思是,我看过一些关于 ProjectionMap 的示例,但是查询所需的键/值是什么?我需要明确写出我想要的值吗?但是,如果它是一个通用方法,而我不知道在那部分代码中我想要得到什么,该怎么办?或者如何将任何查询转换为 ProjectionMap?

我希望我能对此做出解释。

这是我的代码:

     @Override
public boolean onCreate() {
gOpenHelper = new GameDBHelper(getContext());
return true;
}

/**
* Builds a UriMatcher that is used to determine witch database request is being made.
*/
public static UriMatcher buildUriMatcher(){
String content = GamesContract.CONTENT_AUTHORITY;

// All paths to the UriMatcher have a corresponding code to return
// when a match is found (the ints above).
UriMatcher matcher = new UriMatcher(UriMatcher.NO_MATCH);
matcher.addURI(content, GamesContract.PATH_GAME, GAME);
matcher.addURI(content, GamesContract.PATH_GAME + "/#", GAME_ID);

return matcher;
}

@Override
public String getType(Uri uri) {

switch(sUriMatcher.match(uri))
{
case GAME:
return GameEntry.CONTENT_TYPE;
case GAME_ID:
return GameEntry.CONTENT_ITEM_TYPE;
default:
throw new UnsupportedOperationException("Unknown uri: " + uri);
}
}

@Override
public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder) {
final SQLiteDatabase db = gOpenHelper.getWritableDatabase();
Cursor retCursor;
switch(sUriMatcher.match(uri))
{
case GAME:
retCursor = db.query(
GameEntry.TABLE_NAME,
projection,
selection,
selectionArgs,
null,
null,
sortOrder
);
break;
case GAME_ID:
long _id = ContentUris.parseId(uri);

retCursor = db.query(
GameEntry.TABLE_NAME,
projection,
GameEntry._ID + " = ?",
new String[]{String.valueOf(_id)},
null,
null,
sortOrder
);
break;
default:
throw new UnsupportedOperationException("Unknown uri: " + uri);
}
retCursor.setNotificationUri(getContext().getContentResolver(), uri);
return retCursor;
}

@Override
public Uri insert(Uri uri, ContentValues values) {
final SQLiteDatabase db = gOpenHelper.getWritableDatabase();
long _id;
Uri returnUri;

switch(sUriMatcher.match(uri))
{
case GAME:
_id = db.insert(GameEntry.TABLE_NAME, null, values);

if(_id > 0){
returnUri = GameEntry.BuildGameUri(_id);
} else{
throw new UnsupportedOperationException("Unable to insert rows into: " + uri);
}
break;
default:
throw new UnsupportedOperationException("Unknown uri: " + uri);
}

getContext().getContentResolver().notifyChange(uri, null);
return returnUri;
}

@Override
public int delete(Uri uri, String selection, String[] selectionArgs) {
final SQLiteDatabase db = gOpenHelper.getWritableDatabase();
int rows; // Number of rows effected

switch(sUriMatcher.match(uri))
{
case GAME:
rows = db.delete(GameEntry.TABLE_NAME, selection, selectionArgs);
break;
default:
throw new UnsupportedOperationException("Unknown uri: " + uri);
}

// Because null could delete all rows:
if(selection == null || rows != 0){
getContext().getContentResolver().notifyChange(uri, null);
}

return rows;
}

@Override
public int update(Uri uri, ContentValues values, String selection, String[] selectionArgs) {
final SQLiteDatabase db = gOpenHelper.getWritableDatabase();
int rows;

switch(sUriMatcher.match(uri))
{
case GAME:
rows = db.update(GameEntry.TABLE_NAME, values, selection, selectionArgs);
break;
default:
throw new UnsupportedOperationException("Unknown uri: " + uri);
}

if(rows != 0){
getContext().getContentResolver().notifyChange(uri, null);
}

return rows;
}

最佳答案

对于任何可以寻找答案的人来说,这很简单,我认为这对我来说越来越难,因为我不熟悉 Android 上有关 sql 的许多概念。

问题在于需要“where”子句的查询;在我的更新和删除案例中,为了修复它我需要做的是不按原样使用选择参数,我需要做类似的事情:

GamesContract.Games.GAME_NAME + "= ?"

db.delete(GamesContract.Games.TABLE_NAME, GamesContract.Games.GAME_NAME + "= ?", selectionArgs);

基本上是表名+“=?”选择。

这样您就可以强制仅更新所需的表并防止 sql 注入(inject)通过相同的方法修改数据库中的任何位置。

关于android - 修复 Content Provider Android 上的 SQL 注入(inject)漏洞,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53729786/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com