nekuroporisu/android-archives-watchdog
GitHub: nekuroporisu/android-archives-watchdog
一款 Android 归档文件变更监控 CLI 工具,通过基线对比机制在持续集成中捕获新引入的权限和框架组件变更。
Stars: 14 | Forks: 0
# Android Archives Watchdog 🐶
## 概述
`aaw` 是一款命令行工具,结合了
[apkanalyzer](https://developer.android.com/tools/apkanalyzer) 和
[bundletool](https://developer.android.com/tools/bundletool) 的部分功能。
该工具的目标是帮助您检测发布归档文件(`.apk` 或 `.aab`)中新引入的 Android 框架
组件和权限,特别是由第三方项目依赖项带来的传递性
组件和权限,遵循安全左移(shift-left)理念。
`aaw` 以
[真正可执行](https://skife.org/java/unix/2011/06/20/really_executable_jars.html)
的 [fatjar](https://gradleup.com/shadow) 格式分发,并且
已在 Unix 环境下针对 `jdk17` 和 `jdk21` 进行了测试。此外,本项目还针对
以下在 Github 上公开发布开源版本的 Android 产品进行了端到端测试:
- [DuckDuckGo](https://github.com/duckduckgo/Android)
- [ProntonMail](https://github.com/ProtonMail/proton-mail-android)
- [WooCommerce](https://github.com/woocommerce/woocommerce-android)
- [Mozilla Firefox](https://github.com/mozilla-mobile/firefox-android)
## 环境要求
此工具需要 `jdk17` 或更高版本,以及有效的 Android SDK 安装环境。在定位您的 Android SDK 安装目录时,`aaw` 会检查以下环境变量:
- `$ANDROID_HOME`
- `$ANDROID_SDK`
- `$ANDROID_SDK_HOME`
## 安装说明
您可以直接从
[Github 发布页面](https://github.com/dotanuki-labs/android-archives-watchdog/releases)
获取可执行文件。
将其解压并添加到您的 `$PATH` 中。
此外,还有一个
[asdf-plugin](https://github.com/dotanuki-labs/asdf-aaw)
可供使用。
## 使用说明
以下代码片段使用
[ProntonMail](https://github.com/ProtonMail/proton-mail-android)
的发布版本作为示例,特别是
[3.0.7](https://github.com/ProtonMail/proton-mail-android/releases/tag/3.0.7)(2022 年 11 月)和
[3.0.17](https://github.com/ProtonMail/proton-mail-android/releases/tag/3.0.17)(2023 年 10 月)版本。
每个命令均支持 `.apk` 和 `.aab` 格式的归档文件。
### 从 Android 归档文件获取概述
```
$> aaw overview -a tmp/ProtonMail-3.0.7.apk
┌────────────────────────────┬───────────────────────┐
│ Attribute │ Evaluation │
├────────────────────────────┼───────────────────────┤
│ Application Id │ ch.protonmail.android │
├────────────────────────────┼───────────────────────┤
│ Minimum SDK │ 23 │
├────────────────────────────┼───────────────────────┤
│ Target SDK │ 31 │
├────────────────────────────┼───────────────────────┤
│ Total Used Features │ 2 │
├────────────────────────────┼───────────────────────┤
│ Total Manifest permissions │ 14 │
├────────────────────────────┼───────────────────────┤
│ Dangerous permissions │ Yes │
├────────────────────────────┼───────────────────────┤
│ Activities │ 54 │
├────────────────────────────┼───────────────────────┤
│ Services │ 14 │
├────────────────────────────┼───────────────────────┤
│ Broadcast Receivers │ 15 │
├────────────────────────────┼───────────────────────┤
│ Content Providers │ 4 │
└────────────────────────────┴───────────────────────┘
```
此功能模拟了 `apkanalyser` 的相关功能,并支持 `--json` 开关,以便用于自动化目的。
### 从 Android 归档文件生成基线
```
$> aaw generate --archive=tmp/ProtonMail-3.0.7.apk
Baseline available at : ch.protonmail.android.toml
```
此命令将在当前目录生成一个 `.toml` 文件,该文件旨在被保存到您的 VCS 中。此 `toml` 文件会记录来自相关合并后 `AndroidManifest.xml` 的部分信息,即:
- [应用权限](https://developer.android.com/guide/topics/manifest/manifest-intro#perms)
- [设备兼容性](https://developer.android.com/guide/topics/manifest/manifest-intro#compatibility)
- [Activities、Services、Content Providers 和 Broadcast Receivers](https://developer.android.com/guide/topics/manifest/manifest-intro#components)
或者,您可以通过传入“受信任”的包来生成基线的精简版本,这些包通常与您的项目结构相关。它们必须以单个参数的形式传入,并以逗号(`,`)分隔。
```
$> aaw generate --archive=tmp/ProtonMail-3.0.7.apk --trusted='ch.protonmail,me.proton.core'
Baseline available at : ch.protonmail.android.toml
$> more ch.protonmail.android.toml
applicationId = "ch.protonmail.android"
permissions = [
"android.permission.ACCESS_NETWORK_STATE",
"android.permission.FOREGROUND_SERVICE",
"android.permission.GET_ACCOUNTS",
"android.permission.INTERNET",
"android.permission.READ_CONTACTS",
"android.permission.READ_EXTERNAL_STORAGE",
"android.permission.RECEIVE_BOOT_COMPLETED",
"android.permission.SCHEDULE_EXACT_ALARM",
"android.permission.USE_BIOMETRIC",
"android.permission.USE_FINGERPRINT",
"android.permission.VIBRATE",
"android.permission.WAKE_LOCK",
"android.permission.WRITE_EXTERNAL_STORAGE",
"com.google.android.c2dm.permission.RECEIVE"
]
features = [
"android.hardware.faketouch",
"android.hardware.screen.portrait"
]
trustedPackages = [
"ch.protonmail",
"me.proton.core"
]
activities = [
"androidx.biometric.DeviceCredentialHandlerActivity",
"com.google.android.gms.common.api.GoogleApiActivity"
]
.
.
.
```
### 将归档文件与基线进行对比
```
# 考虑到在上一个示例中生成的 baseline 文件
$> aaw compare -a tmp/ProtonMail-3.0.17.apk -b ch.protonmail.android.toml
Your baseline file does not match the supplied artifact.
┌─────────────┬───────────────────────────────────────────────────────────────────┬────────────┐
│ Category │ Finding │ Missing at │
├─────────────┼───────────────────────────────────────────────────────────────────┼────────────┤
│ Permissions │ android.permission.POST_NOTIFICATIONS │ Baseline │
├─────────────┼───────────────────────────────────────────────────────────────────┼────────────┤
│ Permissions │ android.permission.READ_MEDIA_AUDIO │ Baseline │
├─────────────┼───────────────────────────────────────────────────────────────────┼────────────┤
│ Permissions │ android.permission.READ_MEDIA_IMAGES │ Baseline │
├─────────────┼───────────────────────────────────────────────────────────────────┼────────────┤
│ Permissions │ android.permission.READ_MEDIA_VIDEO │ Baseline │
├─────────────┼───────────────────────────────────────────────────────────────────┼────────────┤
│ Components │ com.google.android.play.core.common.PlayCoreDialogWrapperActivity │ Baseline │
├─────────────┼───────────────────────────────────────────────────────────────────┼────────────┤
│ Components │ androidx.profileinstaller.ProfileInstallReceiver │ Baseline │
└─────────────┴───────────────────────────────────────────────────────────────────┴────────────┘
```
此示例说明了如何在持续集成(Continuous Integration)中跟踪敏感变更,前提是您在 CI 运行时生成了可发布归档文件的快照。
如果新的归档文件与现有基线不匹配,`compare` 命令也会以失败状态退出,从而强制要求在 pull/merge request 中更新基线。
```
$> aaw compare -a tmp/ProtonMail-3.0.17.apk -b ch.protonmail.android.toml --fail
```
此外,`compare` 也可以生成 `json` 格式的输出。
```
$> aaw compare -a tmp/ProtonMail-3.0.17.apk -b ch.protonmail.android.toml --json
```
## 鸣谢
此工具的灵感来源于以下博客文章和现有工具
- [Android CI : 在 Pull Request 中展示 Manifest 的更改](https://proandroiddev.com/android-ci-reveal-manifest-changes-in-a-pull-request-a5cdd0600afa)
- [如何对比 apk / aab 文件](https://medium.com/bumble-tech/how-to-compare-apk-aab-files-par-1634563a5af6)
- [Diffuse](https://github.com/JakeWharton/diffuse)
## 许可证
Copyright (c) 2025 - Dotanuki Labs - [MIT 许可证](https://choosealicense.com/licenses/mit/)
标签:Android, DSL, JS文件枚举, Python安全, Shift Left, SOC Prime, 云安全监控, 后台面板检测, 开发工具, 移动开发, 网络调试, 自动化, 质量保证, 静态分析