第3章 SDK隐私风险识别方法论
做SDK合规治理,第一步不是看条款,而是搞清楚你的SDK到底在做什么。我遇到过不少开发者,条款写得很漂亮,代码里却在偷偷传IMEI。这章我就带你捋一遍风险识别的方法论,把重点放在数据流映射、敏感信息识别和第三方SDK风险清单上。
3.1 数据流映射——把隐私流动画出来
说白了,数据流映射就是把你SDK内部的数据“旅行路线”画出来。我个人的习惯是,每次接手新SDK,第一件事就是画这个图。
| 数据流节点 | 描述 | 常见问题 |
|---|---|---|
| 采集点 | 从哪获取数据(API调用、传感器、剪贴板) | 过度采集、非必要采集 |
| 处理逻辑 | 数据如何变换(加密、聚合、匿名化) | 伪匿名化、残留日志 |
| 存储介质 | 数据暂存在哪(内存、本地文件、SharePreference) | 明文存储、未及时清理 |
| 传输通道 | 数据如何出去(HTTP、WebSocket、IPC) | 未加密、跨进程泄露 |
| 第三方落地 | 最终发给谁(服务器、广告平台、统计分析) | 未知接收方、无合约 |
我建议用UML序列图或简单的流程图做映射。工具不重要,关键是把每条数据路径都标出来。曾经有个项目,画完才发现IMEI在启动阶段就被传给一个废弃的统计SDK,而那个SDK早已停止维护。
数据流映射的核心原则:谁、在哪、什么时候、采集了什么数据、发给了谁、存了多久、是否可删除。
3.2 敏感信息识别——盯紧IMEI、MAC、位置
敏感信息不是只有黑白名单。你想想看,IMEI获取可能只在一行代码里。
// 危险:直接读IMEI
TelephonyManager tm = (TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE);
String imei = tm.getDeviceId(); // 需要READ_PHONE_STATE权限
我遇到过最隐蔽的是通过WiFi扫描间接推断位置。明明是“获取周围WiFi列表”的功能,结合几个基站信号强度,就能大致定位。
- IMEI / IMSI / MEID:Android 10+无法直接获取,但getIccId()、getSubscriberId()仍可能被滥用。
- MAC地址:Android 6+已随机化,但部分厂商会暴露真实MAC,尤其通过WifiManager.getConnectionInfo().getMacAddress()。
- 位置:GPS、网络、基站。注意“附近设备扫描”可能触发位置权限。
- 其他“灰色”信息:Android ID、OAID、SSAID、设备序列号。
【我曾踩坑】有一次SDK只在debug构建中打印了IMEI,release版本去掉了。结果用户反馈上线后仍有网络请求携带设备ID——因为混淆保留了Log,但Log被linker吞掉并不代表网络层也去掉了。所以,不要相信干掉的代码,要验证网络包。
3.3 第三方SDK潜在风险清单
你的SDK可能依赖其他SDK,它们之间会互相传递数据,形成风险链。我习惯做一张风险清单表,按优先级排序。
| 风险类型 | 典型场景 | 检查要点 |
|---|---|---|
| 权限升级 | 父SDK声明了权限,子SDK直接使用 | 检查AndroidManifest合并日志 |
| 数据重定向 | 子SDK把IMEI上报给其自有服务器 | 抓包、网络白名单验证 |
| 交互式接口 | 子SDK暴露Activity,可能回传用户操作 | 检查AAR中Activity声明 |
| 隐私政策冲突 | 不同SDK对数据保留期限定义不一致 | 对比各SDK隐私文档 |
| 版本过时 | 老旧SDK使用已废弃的敏感API | 更新至最新合规版本 |
识别方法很简单:用gradle dependencies等工具查看传递依赖树,手动追踪每个子SDK的隐私行为。我曾经发现某个广告SDK内部使用了早期版本的友盟,而友盟又依赖一个日历读写库——整个链条里没人知道日历权限是被谁声明的。
3.4 知识体系总览图
下面这张图概括了整个风险识别方法论的核心逻辑。
3.5 实战流程:从代码到风险清单
光看理论没用,我分享一套我常用的操作步骤。
- 静态扫描:使用工具(例如开源的
checkstyle或lint自定义规则)定位敏感API调用。 - 动态抓包:用Charles或Wireshark录制所有出站流量,过滤目标域名。
- 代码审计:重点关注assets/jniLibs/包装类等不易被扫描到的区域。
- 依赖分析:
./gradlew :module:dependencies --configuration releaseRuntimeClasspath。 - 风险归类:把发现的问题填入风险清单表格,与合规条款逐一对照。
记住:没有元数据的数据流分析,只是假动作。你一定要结合实际的设备行为(比如IMEI是否真的被读取、网络请求是否真的携带了位置),不能只看代码声明。