Android 隐私合规检测

4,386 阅读5分钟

目前应用市场的隐私合规检查越来越严格,各大手机厂商的检测标准也不一致,经常有这个平台过审了那个平台还有问题出现,按照工信部的要求,工信部隐私合规说明。隐私合规是个不可不重视的点。

我们通常遇到的主要问题:
  • 在用户同意隐私协议之前,不能有收集用户隐私数据的行为。例如:在用户同意协议之前不能去获取 Android ID、Device ID、MAC 等隐私数据。

  • 在用户同意隐私协议之后,获取权限时必须要符合当前使用场景,例如:我们需要获取手机读写,相机权限,这种需要在真正的读写,打开相机等页面时才能去请求权限。

如上问题处理可分为两种:权限 和 隐私 
  • 权限 需要在对应页面即 app内获取权限时主动设置弹窗等方式给予app相应的权限
'如电话权限,定位权限,相机权限,浮窗权限,读写权限等。在每个申请危险权限前,都需要弹窗说明权限解释说明。'
  • 隐私 为app使用过程中与用户个人相关的个人信息
'如位置,Mac地址,设备id等。就Android端而言,多数隐私信息需要对应授权后才能获取,但目前仍存在部分隐私信息无需授权就可以拿到的'

如何检测

一、第三方检测

京数安扫描平台国舜网易云盾

二、静态检测
  • Lint 检查项目

    Lint用于检测静态代码和资源,找到其中不符合预定义规则的地方。可参考网易云隐私合规静态检查

  • 反编译查找对应方法

    反编译主要是为了找出第三方的一些不合规方法调用,但是比较麻烦,全局搜索很不方便

三、动态检测(开源)
  • 1、Xposed

    优点 :Xposed 是比较早的做hook的框架, Xposed框架可以在不修改APK文件的情况下影响程序运行(修改系统)的框架服务,基于它可以制作出许多功能强大的模块,且在功能不冲突的情况下同时运作。Android中一般存在两种hook:sdk hook和ndk hook。native hook的难点在于理解ELF文件与学习ELF文件,Java层Hook则需要了解虚拟机的特性与java上的反射使用。另外还存在全局hook,即结合sdk hook和ndk hook,xposed就是一种典型的全局hook框架。

    缺点:需要手机ROOT

  • 2、VirtualXposed

    优点 :VirtualXposed 是基于VirtualApp 和 epic 实现的,能在非ROOT环境下直接运行Xposed模块 (目前支持5.0~10.0)。其实VirtualXposed就是一个支持Xposed的虚拟机,我们把开发好的Xposed模块和对应需要hook的App安装上去就能实现hook功能。

    缺点:步骤相对麻烦,de.robv.android.xposed 的依赖需要翻墙。

  • 3、epic

    优点 :配置简单,属于运行时hook,说明在动态加载dex也能检测到,也是我目前再用的,可以自定义配置hook 对应的类和方法,并找出当前调用线程堆栈,直接定位到调用的方法。

    缺点:兼容问题,Android 11及以上只能支持 64位,不过这个不影响11以下的使用;只检测java类代码,native没有hook 。

  • 4、PrivacySentry

    接入相对复杂,基于自定义transform , 编译期注解+hook方案,第一个transform收集需要拦截的敏感函数,第二个transform替换敏感函数,运行期收集日志,同时支持游客模式。

    有java.util.zip.ZipException: duplicate entry: META-INF/INDEX.LIST 冲突风险。

  • 5、camille

    使用 python Frida 等工具命令,做hook 模块,手机需要Root,功能强大但相对复杂

  • 6、自定义Asm插件,做代码插入检测

    可以在class->dex时,对相应的类、调用方法,做检测。添加我们的拦截代码

四、epic落地
  • 我这里使用的时 epic 检测,直接依赖:
implementation 'me.weishu:epic:1.0.0'
implementation 'me.weishu.exposed:exposed-xposedapi:0.4.5'

主要核心是 DexposedBridge.findAndHookMethod 方法

//targetClass: 传入 需要hook 的类,如:TelephonyManager.class
//targetMethod:类对应的方法,如:getDeviceId
DexposedBridge.findAndHookMethod(targetClass, targetMethod, new XC_MethodHook() {
   @Override
   protected void beforeHookedMethod(MethodHookParam param) throws Throwable {
       super.beforeHookedMethod(param);
   
       //被调用的类名
       String className = param.method.getDeclaringClass().getName();
       //被调用的函数名
       String methodName = param.method.getName();
       LogAction.log("检测到 " + className + " 被调用: methodName=" + methodName);
       //这里可以搜集当前的线程信息,堆栈等,将调用关系打印出来,例如:
     
       //Thread thread = Thread.currentThread();
       //StringBuilder stringBuilder = new StringBuilder();
       //获取线程信息
       //String threadInfo = getThreadInfo(thread);
       //stringBuilder.append(threadInfo);
       // 返回表示此线程的堆栈转储的堆栈跟踪元素数组。
      // 如果这个线程还没有启动,已经启动但还没有被系统计划运行,或者已经终止,这个方法将返回一个零长度的  数组。
       //StackTraceElement[] stackTraceElements = thread.getStackTrace();
       //String print = printToString2(stackTraceElements);
       //stringBuilder.append("线程堆栈日志:").append(print);

       //LogAction.log(stringBuilder);
   }

   @Override
   protected void afterHookedMethod(MethodHookParam param) throws Throwable {
       super.afterHookedMethod(param);
      
   }
});

例如,我这里用了 leakcanary 做检测时会提示的

image.png

因为我对 android.app.ApplicationPackageManager 这个类做了检测,queryIntentActivities 方法被调用时即触发了beforeHookedMethod

五、集成优化处理
  • 我们可以自己定义一个module模块,单独处理合规检测,利用 debugImplementation 的方式集成,不会影响到线上

  • 可以使用 ContentProvider 做初始化入口,debugImplementation 集成进来即可,在 ContentProvider onCreate 的时候去 start启用 需要hook 的集合类。

  • 可以使用企业微信提供 API  Token,在收到 隐私限制方法被调用时,触发消息发送,方便测试和提示,不需要去看log日志。