Android 隐私合规检测
目前应用市场的隐私合规检查越来越严格,各大手机厂商的检测标准也不一致,经常有这个平台过审了那个平台还有问题出现,按照工信部的要求,工信部隐私合规说明。隐私合规是个不可不重视的点。
我们通常遇到的主要问题:
在用户同意隐私协议之前,不能有收集用户隐私数据的行为。例如:在用户同意协议之前不能去获取 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 。
接入相对复杂,基于自定义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
做检测时会提示的
因为我对 android.app.ApplicationPackageManager
这个类做了检测,queryIntentActivities
方法被调用时即触发了beforeHookedMethod
五、集成优化处理
我们可以自己定义一个module模块,单独处理合规检测,利用
debugImplementation
的方式集成,不会影响到线上可以使用
ContentProvider
做初始化入口,debugImplementation
集成进来即可,在ContentProvider onCreate
的时候去 start启用 需要hook 的集合类。可以使用企业微信提供
API Token
,在收到 隐私限制方法被调用时,触发消息发送,方便测试和提示,不需要去看log日志。
链接:https://juejin.cn/post/7213642622074273849
来源:稀土掘金
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。