先分清“提示”和“判定”
Play Protect 的提示可能来自多种信号:安装包被扫描出可疑行为、应用来源不在可信渠道、签名信息异常,或者设备端启发式规则命中了某个模式。它不等于 Google 已经给出最终定性,也不代表应用一定被下架。对开发者和运营来说,最重要的是按可复现的顺序排查,把“可能被误判的点”和“确实需要整改的点”分开。
下面给出一条从低成本到高成本的排查路径:权限 → SDK → 网络传输 → 签名完整性。前两项通常能在本地完成,后两项需要结合构建产物和分发链路一起看。
第一步:权限——先看“申请了但没用到”的项
权限是最容易被规则命中的维度,也是最容易自查的。建议先导出当前线上包的权限清单,与代码实际调用点做对照。
- 危险权限是否与功能匹配:短信、通话记录、通讯录、位置后台、无障碍服务等属于高敏感项,若主流程并不依赖,优先移除或改为按需申请。
- 是否存在“声明了但从未触发”的权限:这类权限最容易在扫描时被标记为可疑,尤其是随第三方库一起合并进来的权限。
- 权限申请时机是否合理:启动即弹窗、拒绝后反复弹窗、诱导开启无障碍等交互,也会放大风险感知。
- 合并后的 Manifest 是否被污染:用构建工具输出最终合并结果,逐条确认来源,而不是只看主模块的声明。
这一步的目标不是“权限越少越好”,而是让每个敏感权限都能对应到明确的功能和用户可见的说明。
第二步:SDK——查来源、查版本、查行为
很多报风险最终落在某个第三方 SDK 上。排查时不要只看依赖名称,要看它实际做了什么。
- 列出全部第三方 SDK 及其版本,标注引入方式(直接依赖、传递依赖、预编译 aar/jar)。
- 核对来源:是否来自官方仓库,是否存在被二次打包、改名或版本号对不上的情况。
- 检查敏感行为:动态加载代码、静默安装、读取已安装应用列表、后台自启动、频繁采集设备标识等,都是高风险模式。
- 确认可关闭项:不少广告或统计 SDK 默认开启多项采集,需要在初始化时显式关闭非必要能力。
- 清理僵尸依赖:已经不再使用的 SDK 应从依赖树中彻底移除,避免只注释调用代码却保留库文件。
如果排查后仍不确定某个 SDK 的行为,可参考站内关于 APK 安全检测与加固服务 的说明,先做静态与动态结合的检测,再决定是否替换。
第三步:网络传输——看明文、看域名、看下载行为
网络层的问题常被忽略,但它同时影响安全扫描结果和用户信任。
- 是否仍存在明文 HTTP 请求:检查网络安全配置,确认没有对全局放开明文流量;确有需要的域名应单独白名单并说明原因。
- 证书校验是否被弱化:全局信任所有证书、关闭主机名校验的代码,容易被判定为高风险。
- 是否存在动态下发可执行内容:从网络下载 dex、so 或脚本并加载,是扫描重点关注的行为,应确认业务必要性并加固校验。
- 下载与更新链路是否可信:更新包来源、校验方式、是否校验签名,都要能说清楚。
- 回连域名是否稳定可信:频繁更换、使用可疑后缀或硬编码 IP 的通信地址,会拉高风险评分。
第四步:签名完整性——确认包没被改过
签名问题往往意味着分发链路出了问题,优先级应高于代码层优化。
- 比对签名指纹:将线上包与构建系统产出的包做签名证书比对,确认一致。
- 确认签名方案:检查 v1/v2/v3 签名是否齐全,是否因工具链问题导致部分方案缺失。
- 检查是否被二次打包:对比文件清单、资源与入口配置,确认没有外部注入的组件或广告代码。
- 核对分发渠道:非官方渠道分发的包是否被替换过,下载页是否可能被劫持。
- 确认密钥管理:签名密钥是否只在受控环境使用,是否存在多人共用或明文存放。
如果确认包被篡改,应先止损——暂停问题渠道分发、替换安装包、通知用户,再回到代码层排查。关于密钥与签名管理的规范,可参考 关于我们 中的安全实践说明。
整改材料怎么准备
排查完成后,建议整理一份简短说明:每个敏感权限对应的功能、每个第三方 SDK 的用途与版本、网络请求的域名与用途、签名指纹与分发渠道。这份材料既能用于内部复盘,也能在需要申诉或向渠道说明时直接使用。顺序上先做权限和 SDK 的清理,再做网络与签名的加固,通常能以较低成本消除大部分误判来源。