Android动态权限分析工具

审核对数据的访问

您可以通过执行数据访问审核来了解您的应用及其依赖项如何访问用户的私密数据。此流程在搭载 Android 11(API 级别 30)及更高版本的设备上可用,可让您更好地识别可能出现的意外数据访问。您的应用可以注册 AppOpsManager.OnOpNotedCallback 实例,该实例可在每次发生以下任一事件时执行相应操作:

  • 应用的代码访问私密数据。为了帮助您确定应用的哪个逻辑部分调用了事件,您可以按归因标记审核数据访问。
  • 依赖库或 SDK 中的代码访问私密数据。

数据访问审核是在发生数据请求的线程上调用的。这意味着,如果应用中的第三方 SDK 或库调用访问私密数据的 API,您的 OnOpNotedCallback 可以调用数据访问审核检查有关该调用的信息。通常,此回调对象可以通过查看应用的当前状态(例如当前线程的堆栈轨迹)以判断调用是来自您的应用还是来自 SDK。

记录数据访问

如需使用 AppOpsManager.OnOpNotedCallback 实例执行数据访问审核,请在您打算审核数据访问的组件中实现回调逻辑,例如在某个 Activity 的 onCreate() 方法中。

注意:如果您的应用在多个组件(例如在前台服务和后台任务)中访问数据,请创建自定义子类 Application,并在子类的 onCreate() 方法中定义 AppOpsManager.OnOpNotedCallback

以下代码段定义了在单个 Activity 中用于审核数据访问的 AppOpsManager.OnOpNotedCallback:

@Override
public void onCreate(@Nullable Bundle savedInstanceState,
        @Nullable PersistableBundle persistentState) {
    AppOpsManager.OnOpNotedCallback appOpsCallback =
            new AppOpsManager.OnOpNotedCallback() {
        private void logPrivateDataAccess(String opCode, String trace) {
            Log.i(MY_APP_TAG1

, "Private data accessed. " +
                    "Operation: $opCode\nStack Trace:\n$trace");
        }

        @Override
        public void onNoted(@NonNull SyncNotedAppOp syncNotedAppOp) {
            logPrivateDataAccess(syncNotedAppOp.getOp(),
                    Arrays.toString(new Throwable().getStackTrace()));
        }

        @Override
        public void onSelfNoted(@NonNull SyncNotedAppOp syncNotedAppOp) {
            logPrivateDataAccess(syncNotedAppOp.getOp(),
                    Arrays.toString(new Throwable().getStackTrace()));
        }

        @Override
        public void onAsyncNoted(@NonNull AsyncNotedAppOp asyncNotedAppOp) {
            logPrivateDataAccess(asyncNotedAppOp.getOp(),
                    asyncNotedAppOp.getMessage());
        }
    };

    AppOpsManager appOpsManager = getSystemService(AppOpsManager.class);
    if (appOpsManager != null) {
        appOpsManager.setOnOpNotedCallback(getMainExecutor(), appOpsCallback);
    }
}

在特定情况下,需要调用 onAsyncNoted()onSelfNoted() 方法:

  • 如果数据访问并非发生在应用调用 API 期间,需要调用 onAsyncNoted()。最常见的一个例子就是,在您的应用注册了监听器后,每次调用该监听器的回调时都会发生数据访问。

    传递到 onAsyncNoted() 中的 AsyncNotedOp 参数包含名为 getMessage() 的方法。此方法提供了有关数据访问的详细信息。如果是位置信息回调,该消息将包含监听器的系统身份哈希值。

  • 在极少数情况下,如果应用将自身的 UID 传递到 noteOp(),需要调用 onSelfNoted()

按归因标记审核数据访问

您的应用可能有几种主要用例,例如允许用户拍照并与联系人分享这些照片。如果您开发的是一款多用途应用,可以在审核应用的数据访问时对应用的各部分使用归因标记。在传递到 onNoted() 调用的对象中会返回 attributionTag 上下文。这可以帮助您更轻松地将数据访问回溯至代码的逻辑部分。

如需在应用中定义归因标记,请完成以下部分中的步骤。

创建归因标记

如果您在某个 Activity 中访问数据(例如请求位置信息或访问用户的联系人列表),请在该 Activity 的 onCreate() 方法中调用 createAttributionContext(),并传入您希望与应用的一部分相关联的归因标记。

以下代码段展示了如何为应用的“照片位置信息分享”部分创建归因标记:

public class SharePhotoLocationActivity extends AppCompatActivity {
    private Context attributionContext;

    @Override
    public void onCreate(@Nullable Bundle savedInstanceState,
            @Nullable PersistableBundle persistentState) {
        attributionContext = createAttributionContext("sharePhotos");
    }

    public void getLocation() {
        LocationManager locationManager =
                attributionContext.getSystemService(LocationManager.class);
        if (locationManager != null) {
            // Use "locationManager" to access device location information.
        }
    }
}

在访问日志中包含归因标记

更新您的 AppOpsManager.OnOpNotedCallback 回调,以将您定义的归因标记的名称包含于应用的日志中。

注意:如果归因标记的返回值为 null,意味着当前的 Context 对象与您应用的主要部分相关联。

以下代码段展示了记录归因代码的更新逻辑:

@Override
public void onCreate(@Nullable Bundle savedInstanceState,
        @Nullable PersistableBundle persistentState) {
    AppOpsManager.OnOpNotedCallback appOpsCallback =
            new AppOpsManager.OnOpNotedCallback() {
        private void logPrivateDataAccess(String opCode,
                String attributionTag, String trace) {
            Log.i("MY_APP_TAG", "Private data accessed. " +
                    "Operation: $opCode\n " +
                    "Attribution Tag:$attributionTag\nStack Trace:\n$trace");
        }

        @Override
        public void onNoted(@NonNull SyncNotedAppOp syncNotedAppOp) {
            logPrivateDataAccess(syncNotedAppOp.getOp(),
                    syncNotedAppOp.getAttributionTag(),
                    Arrays.toString(new Throwable().getStackTrace()));
        }

        @Override
        public void onSelfNoted(@NonNull SyncNotedAppOp syncNotedAppOp) {
            logPrivateDataAccess(syncNotedAppOp.getOp(),
                    syncNotedAppOp.getAttributionTag(),
                    Arrays.toString(new Throwable().getStackTrace()));
        }

        @Override
        public void onAsyncNoted(@NonNull AsyncNotedAppOp asyncNotedAppOp) {
            logPrivateDataAccess(asyncNotedAppOp.getOp(),
                    asyncNotedAppOp.getAttributionTag(),
                    asyncNotedAppOp.getMessage());
        }
    };

    AppOpsManager appOpsManager = getSystemService(AppOpsManager.class);
    if (appOpsManager != null) {
        appOpsManager.setNotedAppOpsCollector(appOpsCollector);
    }
}


资料来源:https://developer.android.google.cn/guide/topics/data/audit-access#java

你可能感兴趣的:(Android动态权限分析工具)