☰
OWASP MASTG 深度解析:Android Activity 组件、Intent 访问控制与攻击面评估
2026/10/7 22:43:40 网站建设 项目流程
  • 文档
  • 教程
  • 网络安全

【免费下载链接】mastg

The OWASP Mobile Application Security Testing Guide (MASTG) is a comprehensive manual for mobile app security testing and reverse engineering. It describes technical processes for verifying the OWASP Mobile Security Weakness Enumeration (MASWE) weaknesses, which are in alignment with the OWASP MASVS.

项目地址:https://gitcode.com/gh_mirrors/ow/mastg
点击查看免费下载

本指南基于 OWASP MASTG(Mobile Application Security Testing Guide)知识库中的 Android Activities 专题(MASTG-KNOW-0132),系统讲解 Activity 的声明方式、生命周期、显式/隐式 Intent 启动机制、<intent-filter>解析规则,以及以android:exported和android:permission为核心的组件访问控制模型。文中结合 MASTG 仓库中的测试用例(MASTG-TEST-0364)、技术条目(MASTG-TECH-0160)、最佳实践(MASTG-BEST-0052)与静态分析规则(semgrep YAML 规则),说明安全测试人员如何枚举导出 Activity、识别敏感功能暴露风险并验证加固措施。读完本文,你将掌握 Activity 作为 IPC 入口点的完整安全评估方法,并能在实际项目中正确配置组件可见性。

Activity 是什么:一个屏幕,也是 IPC 入口点

Activity 是 Android 应用组件(app component)之一,它提供一个带有用户界面的独立屏幕。一个应用通常为每个屏幕实现一个 Activity——例如一个三屏应用就实现三个 Activity。每个 Activity 都继承自Activity类或其子类(如AppCompatActivity),并在其中承载该屏幕的界面元素,包括 Fragment、View 与布局。

从安全视角看,Activity 的独特之处在于:它是进程间通信(IPC)的入口点之一。MASTG 的 IPC 模型条目 MASTG-KNOW-0020 明确指出,Android 中有四类组件充当 IPC 入口点:

  • Activities:提供可由其他应用启动的 UI 屏幕;
  • Services:运行其他应用可启动或绑定的后台任务;
  • Broadcast Receivers:响应来自其他应用与系统的广播消息;
  • Content Providers:通过基于 URI 的接口暴露结构化数据。

所有组件都在AndroidManifest.xml中声明,其对外可见性由android:exported属性及可选的权限属性控制。其他应用或系统可以通过发送Intent来启动 Activity,但这种启动受到清单访问控制(如android:exported和android:permission)的约束——这正是 Activity 可见性与应用攻击面直接相关的根本原因。

声明:不声明的 Activity 无法被显示

每个 Activity 必须在AndroidManifest.xml中用<application>内嵌套的<activity>元素声明:

<activity android:name=".MainActivity" />

关键约束:未在清单中声明的 Activity 无法被显示,尝试启动它会抛出异常。系统在 Activity 启动时才实例化它,并将用户交互与生命周期事件路由给它。安全测试的第一步(静态分析)通常就是检查清单,确认应用中到底声明了哪些 Activity——详见后文"枚举导出的 Activity"一节。

生命周期:系统管理的状态机

Activity 的生命周期由 Android 系统管理。一个 Activity 可以处于多种状态之一(created、started、resumed、paused、stopped、destroyed 等),并在状态迁移时收到对应的回调。最常见的回调包括:

  • onCreate:初始化 Activity,通常在此构建用户界面;
  • onStart、onResume:Activity 变为可见,随后变为可交互;
  • onPause、onStop:Activity 失去焦点,随后失去可见性;
  • onDestroy:Activity 正在被销毁,在此释放资源;
  • onSaveInstanceState与onRestoreInstanceState:持久化并恢复瞬态 UI 状态(如旋转屏幕时的输入内容)。

完整流程参见 The activity lifecycle。对安全测试而言,生命周期回调是定位"敏感操作发生点"的重要锚点:例如深链处理代码常写在onCreate中(见 MASTG-DEMO-0152 的DeepLinkActivity.onCreate),而onNewIntent则处理应用已在前台运行时再次收到 Intent 的情况。

启动 Activity:显式 Intent 与隐式 Intent

一个 Activity 通过向startActivity传递Intent来启动;当需要返回值时,使用 Activity Result APIs:

  • 显式 Intent(Explicit):通过目标组件的类名或包名指名道姓地指定目标组件。典型场景是启动应用内部组件,因为调用方明确知道目标 Activity/Service 的类:

    Intent downloadIntent = new Intent(this, DownloadActivity.class); downloadIntent.setAction("android.intent.action.GET_CONTENT"); startActivityForResult(downloadIntent);

    显式 Intent 也可以跨应用启动已导出的组件(在访问控制允许的前提下)。

  • 隐式 Intent(Implicit):不指定目标组件,只声明一个 action(以及可选的 data 与 categories),由系统根据已安装应用声明的<intent-filter>解析由哪个组件处理。例如,调用方可以用隐式 Intent 在地图上显示某个位置,而不必指定具体的某个地图应用:

    Intent downloadIntent = new Intent(); downloadIntent.setAction("android.intent.action.GET_CONTENT"); startActivityForResult(downloadIntent);

Intent 解析算法

系统收到隐式 Intent 后,会将 Intent 与所有已安装组件声明的<intent-filter>进行比对(intent resolution algorithm),评估以下匹配准则:

  • Action:filter 必须声明与 Intent 相同的 action 字符串;
  • Category:Intent 中的所有 category 都必须出现在 filter 中;filter 可以额外声明更多 category;
  • Data:URI 的 scheme、host、path 与 MIME type 必须满足 filter 中<data>的约束。

如果解析出多个匹配组件,系统可能弹出 chooser/消歧对话框让用户选择;如果只有一个匹配组件,则直接路由。

两个重要的平台行为值得安全测试人员注意:

  1. 隐式 Intent 默认附加CATEGORY_DEFAULT:对于隐式启动 Activity,filter 通常需要声明CATEGORY_DEFAULT类别,因为startActivity会像隐式 Intent 已包含该类别一样处理它。
  2. Android 14 收紧隐式 Intent 到内部组件:如果应用 targetSdk 为 Android 14(API level 34)或更高,隐式 Intent永远不会被发送到内部组件(见 Android 14 behavior changes)。这强制开发者对内部通信使用显式 Intent。

包级限定解析

Intent.setPackage可以把解析范围限制在指定包内,同时仍保留基于 action 的匹配语义——这是"半显式"的常用折中方案:

val intent = Intent("com.example.app.INTERNAL_ACTION").apply { setPackage("com.example.app") } startActivity(intent)

MASTG 仓库为此提供了对应的静态分析规则 mastg-android-implicit-intent-internal-communication.yml,通过 semgrep 模式检测"用隐式 Intent 做内部组件通信"的写法(new Intent(...)+setAction(...)+startActivity(...)),并在缺少setPackage(...)/setComponent(...)时告警,消息内容为[MASVS-CODE-4]内部组件通信应使用显式 Intent。

Intent Filters:活动能力声明,而非安全边界

<intent-filter>声明一个 Activity 能够响应的 actions、categories 与 data。最典型的例子是 launcher activity(启动入口),它声明MAINaction 与LAUNCHERcategory:

<activity android:name=".MainActivity" android:exported="true"> <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity>

一个 Activity 只有在声明了匹配的 intent filter 时,才能被隐式 Intent 启动。但必须强调 MASTG 知识库中的安全要点:Intent filters 不是访问控制机制——要控制哪些外部调用方可以启动 Activity,应使用android:exported和权限(permissions)。

Deep Links 是 intent filter 的一种特殊用例,它将 Web URI 或自定义 URI 映射到 Activity(参见 MASTG-KNOW-0019)。一个可浏览的 Web 深链通常组合了android.intent.action.VIEWaction、android.intent.category.DEFAULT与android.intent.category.BROWSABLE类别,以及一个或多个定义scheme、host、path的<data>元素。同一条<intent-filter>内的多个<data>元素会按属性组合全部合并。

深链安全的核心风险是deep link collision(深链冲突):设备上任意其他应用都能声明与目标应用完全相同的深链,导致系统弹出消歧对话框,用户可能误选恶意应用。Android App Links(基于http/https且经 Digital Asset Links 验证)可缓解此问题,但自定义 URL scheme(如myapp://)不受系统验证。MASTG 还提供了规则 mastg-android-custom-deeplink-scheme.yml 定位自定义 scheme 声明,以及 mastg-android-deeplink-unvalidated-parameter.yml 定位getIntent().getData()/getQueryParameter(...)这类深链入口与参数读取点。

访问控制:android:exported 与 android:permission

其他应用能否启动某个 Activity,由清单属性决定。MASTG-KNOW-0132 将其归纳为三个要素:

属性/元素作用关键语义
android:exported是否允许其他应用启动为true时,其他应用的组件可以启动该 Activity(除非android:permission等机制阻止调用方);为false时,只有同应用、共享同一 user ID 的应用或特权系统组件可以启动。默认值为false(当 Activity 没有 intent filter 时)。
<intent-filter>声明 Activity 能接收的隐式 Intent历史上,声明了 intent filter 且未显式设置android:exported的 Activity,在较老的 target SDK 版本上可能被其他应用触达。依赖默认值是被明确劝阻的:targetSdk 为 Android 12(API level 31)或更高 的应用,凡带有 intent filter 的 Activity 必须显式声明android:exported,否则应用无法安装。
android:permission要求调用方持有特定权限调用方未持有该权限时,Intent 不会投递给 Activity。结合自定义权限与合适的android:protectionLevel(例如signature),可将可交互的应用限制到特定集合。

关于权限保护级别与自定义权限的完整模型(normal、signature、signatureOrSystem、dangerous、appop等),参见 MASTG-KNOW-0017;关于"导出组件基于权限的访问控制"官方说明,参见 Permission-based access control to exported components。

最佳实践:默认不导出,导出必有权限

MASTG 最佳实践 MASTG-BEST-0052(Restrict Access to Android App Components)给出了落地准则:

  1. 仅在另一应用确实需要交互时才导出组件。每个导出组件都是设备上其他应用可能调用的入口点,默认保持私有可缩小攻击面。
  2. 显式设置android:exported="false",不要依赖默认值——默认值在不同 Android 版本和组件类型间变化过,且 intent filter 历史上会让组件"被导出"。自 Android 12(API level 31)起,任何带 intent filter 的 Activity/Service/Receiver 都必须显式声明android:exported。
  3. 仅内部使用的组件应移除<intent-filter>,改用显式 Intent 触达;需要被另一个受信任应用访问时,用android:exported="true"配合合适权限(通常为signature)。
  4. 不要把android:permission的存在当作充分条件:normal或dangerous这类可广泛授予的保护级别仍可能让不可信应用调用敏感组件。

自定义权限的声明示例(定义在组件拥有方或其他可信包的清单中):

<permission android:name="com.example.app.permission.SEND_INTERNAL_BROADCAST" android:protectionLevel="signature" />

安全测试实践:枚举导出的 Activity

从安全测试角度,第一步是确定应用的"可触达面"——即哪些 Activity 被导出。MASTG 技术条目 MASTG-TECH-0160(Enumerating Activities)系统给出了四种方法,建议优先做清单静态分析(无需设备,且精确反映声明内容),需要确认运行时行为时再结合设备工具。

1. 直接分析 AndroidManifest

提取并解码AndroidManifest.xml(参见 MASTG-TECH-0117)后,查找<activity>与<activity-alias>元素,记录其android:name、android:exported、android:permission和 intent filter。注意activity alias 有自己的android:exported、android:permission与 intent filter,需要与目标 Activity 分开审查。

用xmlstarlet可以一次性列出每个 Activity/别名及其关键属性:

xmlstarlet sel -t -m "//activity | //activity-alias" -v "name()" -o " name=" -v "@android:name" -o " exported=" -v "@android:exported" -o " permission=" -v "@android:permission" -o " intent_filters=" -v "count(intent-filter)" -n AndroidManifest.xml

解读android:exported时必须结合 intent filter、target SDK、Android 版本与关联权限:targetSdk 为 Android 11 或更低的应用,任何声明了<intent-filter>且未设android:exported="false"的 Activity 都可能被其他应用触达;targetSdk 为 Android 12(API level 31)或更高的应用则必须显式声明,否则无法安装。

2. 使用 aapt2 快速查看

aapt2无需解码完整 XML 即可打印清单中声明的组件:

aapt2 d xmltree app.apk --file AndroidManifest.xml | grep -A20 -E "E: activity|E: activity-alias"

逐块检查每个 activity 的android:name、android:exported、android:permission及嵌套的intent-filter。在原始输出中,android:exported="true"显示为0xffffffff。嵌套的intent-filter只是"需要结合 target SDK 与版本规则解读"的信号,本身并不直接证明组件已导出。

3. 使用 adb 查询运行时状态

在装有应用的设备或模拟器上,可以查询包管理器的解析表:

adb shell dumpsys package <package_name> | awk '/^Activity Resolver Table:/{show=1} /^Receiver Resolver Table:/{show=0} show' adb shell cmd package query-activities --components -p <package_name> -a android.intent.action.MAIN -c android.intent.category.LAUNCHER

dumpsys package可查看 activity resolver table 及其关联的permission值;cmd package query-activities适合快速分诊,但它只是针对给定包、action、category 的 intent 解析视图,不能枚举包声明的所有 Activity。

启动导出的 Activity 并观察其行为:

# 按组件名启动 adb shell am start -n <package_name>/<activity_name> # 指定 action 与 category 启动 adb shell am start -n <package_name>/<activity_name> -a android.intent.action.MAIN -c android.intent.category.LAUNCHER

历史测试用例 MASTG-TEST-0029(已废弃,被 MASTG-TEST-0364 等覆盖)曾以脆弱密码管理器 Sieve 演示:其.PWList与.FileSelectActivity均带android:exported="true",可直接用adb shell am start -n com.mwr.example.sieve/.PWList启动,从而绕过MainLoginActivity的登录验证直接访问密码数据——这是"导出 Activity 绕过认证"的典型利用链。

4. 使用 drozer 兜底

当清单与 adb 检查不足时,drozer 可以枚举导出 Activity 及其权限,并提供构造 Intent 的辅助命令:

run app.activity.info -a <package_name> run app.activity.start --component <package_name> <activity_name>

测试用例视角:导出且未受保护的敏感 Activity

MASTG 的 V2 测试用例 MASTG-TEST-0364(Exported And Unprotected Activities That Expose Sensitive Functionality,对应 MASWE-0018)将该主题固化为可重复执行的测试流程:

步骤:先用 MASTG-TECH-0013 逆向应用 → 用 MASTG-TECH-0117 获取AndroidManifest.xml→ 用 MASTG-TECH-0160 列出导出 Activity 及其android:permission→ 用 MASTG-TECH-0014 检查每个导出 Activity 的代码实现。

判定失败条件:任一导出 Activity 未受合适的android:permission保护、且暴露或执行敏感功能,例如:

  • 显示或返回敏感数据(账户详情、消息、存储的密钥);
  • 执行安全相关操作(修改设置或凭据);
  • 直接启动可绕过应用其他路径依赖的认证步骤(如登录或 PIN 屏)。

进一步验证(使用 MASTG-TECH-0023 深入审查):判断该 Activity 是否有正当理由被第三方应用启动——如果没有,就不应导出;如果确实需要外部访问,则判断android:permission或其他等效控制是否与功能敏感度及允许的调用方集合匹配,并验证权限在该信任边界内是否真正有效(例如使用signature保护级别,或其他不会被不可信应用广泛获取的控制)。

与之呼应的还有 V2 测试 MASTG-TEST-0355 与 MASTG-TEST-0356(覆盖原 MASTG-TEST-0007 的存储数据经 IPC 泄露检查,涵盖 Provider 与 FileProvider 场景),以及深链参数校验测试 MASTG-TEST-0394。

仓库实证:深链处理器的未校验参数案例

MASTG 仓库的演示用例 MASTG-DEMO-0152 完整演示了"自定义 URL scheme + 未校验参数"的失败样本:应用在DeepLinkActivity上注册自定义 schememastestapp://transfer,设备上任意应用都能打开它(例如mastestapp://transfer?amount=9999999)。

该 Activity 的入口DeepLinkActivity.onCreate通过getIntent().getData()读取 URI,随后在MastgTest中用getQueryParameter("amount")提取amount参数,并直接以原始String传入processTransfer(),全程没有toLong()转换或范围检查:

String amount = data.getQueryParameter("amount"); // raw String from the URI ... return processTransfer(amount); // used as-is ... private final String processTransfer(String amount) { return "Transferring " + amount + " units"; // no toLong(), no bounds check }

配合 semgrep 规则 mastg-android-deeplink-unvalidated-parameter.yml(匹配$INTENT.getData()与$URI.getQueryParameter(...)),静态扫描即可定位深链入口与参数读取点,再结合 MASTG-TECH-0023 人工确认参数是否被验证。该用例与本文的关联在于:任何应用都能发送匹配导出 intent filter 的 Intent——与 iOS 不同,Android 没有内建机制让深链处理器识别发送方应用(iOS 可通过sourceApplication获取调用方 bundle identifier),因此深链参数必须视为不可信输入。

总结:Activity 安全评估清单

结合原知识条目与仓库内测试、规则、最佳实践,可将 Android Activity 的安全评估浓缩为以下可操作清单:

  1. 声明检查:在AndroidManifest.xml中列出全部<activity>与<activity-alias>(用xmlstarlet或aapt2),确认是否存在未声明组件。
  2. 导出状态显式化:每个带<intent-filter>的 Activity 显式声明android:exported;仅内部使用的组件移除 filter 并用显式 Intent 触达(targetSdk ≥ 31 时这是安装硬性要求)。
  3. 权限配套:确实需要导出的 Activity,评估android:permission+protectionLevel(优先signature)是否与功能敏感度匹配;警惕normal/dangerous级别可被广泛授予的问题。
  4. 运行时验证:用adb shell am start直接启动导出 Activity,确认是否存在绕过认证、泄露数据或执行敏感操作的可能(参见 MASTG-TEST-0364 的评估标准)。
  5. 深链单独审查:对声明了 VIEW action + BROWSABLE category 的 Activity,检查深链参数(getQueryParameter等)是否经过类型转换、边界检查或白名单验证,警惕 deep link collision(参见 MASTG-DEMO-0152)。

Activity 既是应用功能的最小组成单元,也是攻击面暴露的最常见载体。将"默认不导出、导出必有权限、入口必校验"三条原则落地,配合 MASTG 提供的测试用例与 semgrep 规则做持续集成检查,即可系统性地控制这一 IPC 入口点的风险。

  • 文档
  • 教程
  • 网络安全

【免费下载链接】mastg

The OWASP Mobile Application Security Testing Guide (MASTG) is a comprehensive manual for mobile app security testing and reverse engineering. It describes technical processes for verifying the OWASP Mobile Security Weakness Enumeration (MASWE) weaknesses, which are in alignment with the OWASP MASVS.

项目地址:https://gitcode.com/gh_mirrors/ow/mastg
点击查看免费下载

相关推荐

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询