引言
诸如读写外置存储、读取联系人、发短信等隐私权限,android在6.0系统开始进行动态授权。但在我国,仅向用户提示授权框还不够,工信部在19年11月初发布了专项整治App八类侵权行为审明 ,其文明确治理以下八类问题:
1.私自收集个人信息;
2.超范围收集个人信息;
3.私自共享给第三方用户信息;
4.强制用户使用定向推送功能;
5.不给权限不让用;
6.频繁申请权限;
7.过度索取权限;
8.为用户账号注销设置障碍。
很不幸,网报通告批评:我司老版本APP中审明了隐私权限,但在隐私文档中并未进行有效说明。收到通告,团队立马对权限进行了扫描,发现APP在AndroidManifest中审明了三项隐私权限,但实际过程并未使用(有些冤大头)。我相信很多团队跟我们面临同个问题,多团队开发下,权限引入问题没有一个有效监管机制。为避免类似问题再次发生,本文给出一个简单有效的代码编译层拦截方案。
在说方案原理之前,我们先假定检测方案是扫描APP AndroidManifest.xml文件中审明的和用户有关的隐私权限,再比对隐私文档以及实际使用场景,进行判别。面对检测方案,我们给出解决思路:
在编译阶段processApplicationManifest task运行后,对Merged Manifest Log文件进行扫描,如果用到了新权限,抛出打包错误,直至问题解决;
源码简阅
Android Gradle Plugin在编译APP后,会在build/outputs/logs目录下生成名为【manifest-merger-${variantname}-report.txt】文本文件。
以AGP 3.5.0源码为例,简单分析下ProcessApplicationManifest任务是如何产生Merged Manifest Log文件的。
package com.android.build.gradle.tasks;
/** A task that processes the manifest */
@CacheableTask
public abstract class ProcessApplicationManifest extends ManifestProcessorTask {
@Override
@Internal
protected boolean getIncremental() {
return true;
}
@Override
protected void doFullTaskAction() throws IOException {
... ...
MergingReport mergingReport =
ManifestHelperKt.mergeManifestsForApplication(
getMainManifest(),
getManifestOverlays(),
computeFullProviderList(compatibleScreenManifestForSplit),
navigationXmls,
getFeatureName(),
moduleMetadata == null
? getPackageOverride()
: moduleMetadata.getApplicationId(),
moduleMetadata == null
? apkData.getVersionCode()
: Integer.parseInt(moduleMetadata.getVersionCode()),
moduleMetadata == null
? apkData.getVersionName()
: moduleMetadata.getVersionName(),
getMinSdkVersion(),
getTargetSdkVersion(),
getMaxSdkVersion(),
manifestOutputFile.getAbsolutePath(),
// no aapt friendly merged manifest file necessary for applications.
null /* aaptFriendlyManifestOutputFile */,
metadataFeatureManifestOutputFile.getAbsolutePath(),
bundleManifestOutputFile.getAbsolutePath(),
instantAppManifestOutputFile != null
? instantAppManifestOutputFile.getAbsolutePath()
: null,
ManifestMerger2.MergeType.APPLICAT