Android13 加强Intent filters 的安全性
作者:??TechMerger???? 发布时间:2022-06-17 03:15:55
前言:
在看这个变更之前,我们需要回忆下 Android 12 的一个安全性变更, 即声明了 <intent-filter>
的Activity、BroadcastReceiver、Service 必须声明 android:exported
, 否则将会无法被启动。
Android 12 的这个变更是为了防止开发者在不知情的情况下,声明了一个 intent-filter 就会使得这些组件对外公开,一定程度下强化了安全性。
但是却漏掉了显式 Intent 启动和 Broadcast Receiver 动态注册两种情况,便在 13 中分别推出了两项变更来进行加强。
Intent filters block non- -matching intents
Safer exporting of context- -registered receivers
Intent filters block non-matching intents
Android 13 开始 Intent 过滤器会屏蔽不匹配的 intent,即便是指定了 Component 的显式启动。
在 13 以前:
开发者想给 Component 添加 支持
这个 需要公开给外部 App 使用,便设定了 Component exported 为 true
这时候该 Component 就出现了一个安全漏洞:外部 App 使用不同于 中声明的 Action,甚至 mimeType 都不匹配均可以启动它
也许你觉得这并没有什么,但是如果 App 只针对 过来的 Route 做了安全校验,就造成了校验上的疏漏。
具体变更
假如我们提供了的 Activity 像如下一样声明:
<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>
<intent-filter>
<action android:name="android.intent.action.TEST" />
<data android:mimeType="vnd.android.cursor.dir/event"/>
</intent-filter>
</activity>
在 13 之前,其他 App 采用了显式启动,即便是错误的 ACTION 是可以正常启动我们的 Activity。
private fun testIntentFilters() {
Intent().setComponent(
ComponentName("com.example.demoapplication",
"com.example.demoapplication.MainActivity")
).apply {
action = "android.intent.action.TEST_A"
startActivity(this)
}
}
而运行在 13 上的话,将无法启动并会发生如下错误:
PackageManager: Intent does not match component's intent filter: Intent { act=android.intent.action.TEST_A cmp=com.example.demoapplication/.MainActivity }
PackageManager: Access blocked: ComponentInfo{com.example.demoapplication/com.example.demoapplication.MainActivity}
除了 ACTION 修改正确以外,data 也要满足即 Intent-filter 完全符合才可以启动。
private fun testIntentFilters() {
Intent().setComponent(
ComponentName("com.example.demoapplication",
"com.example.demoapplication.MainActivity")
).apply {
action = "android.intent.action.TEST"
data = CalendarContract.Events.CONTENT_URI
startActivity(this)
}
}
豁免
如下的几种场景下的 Intent 并不在本次变更的影响范围内:
目标 Component 没有声明
<intent-filter>
同一个 App 内部发出的 Intent
系统发出的 Intent,包括
SystemServer
、采用 System UID 的系统 AppRoot
进程发出的 Intent
适配办法
如果目标运行的版本基于 Android 13,并且不是上述豁免对象的话,需要做些检查和必要的修改。
按照启动方和目标方两种情况进行适配办法的探讨:
作为启动方:
startActivity()
startActivityForResult()
sendBroadcast()
是否存在采用显式 Intent 方式启动其他 App 或发送广播的情况
该 Component 是否声明了
<intent-filter>
防止其 Target 升级到了 Android 13 无法正常启动,需要注意 Intent 的 action、data 等信息是否准确
作为目标方:
Target 是否需要升级到 Android 13
是否对外提供了 Component 并声明了
<intent-filter>
防止无法被正常启动,需要告知启动方
<intent-filter>
的信息
残留
13 上实测发现 Service 组件在显式启动下,即便是错误的 ACTION,仍能被正常启动。这是有意为之还是 Beta 版漏洞,源码尚未公开,原因未知。
startService()
startForegroundService()
bindService()
Safer exporting of context-registered receivers
为了帮助提高运行时 * 的安全性,Android 13 允许您指定您应用中的特定广播 * 是否应被导出以及是否对设备上的其他应用可见。
如果导出广播 * ,其他应用将可以向您的应用发送不受保护的广播。此导出配置在以 Android 13 或更高版本为目标平台的应用中可用,有助于防止一个主要的应用漏洞来源。
具体变更
TargetSDK 升级到 Android13 的 App 在动态注册 Receiver 的时候不指明该 flag,那么会收到如下的 crash:
java.lang.SecurityException: com.example.demoapplication: One of RECEIVER_EXPORTED or RECEIVER_NOT_EXPORTED should be specified when a receiver isn't being registered exclusively for system broadcasts
目前上述限制不是默认生效的,需要开启如下兼容性变更:
开发者选项 -> App Compatibility Changes -> Your App ->
DYNAMIC_RECEIVER_EXPLICIT_EXPORT_REQUIRED
另外,当你的 Receiver 声明了 RECEIVER_NOT_EXPORTED 的话,其他 App 向其发送广播会失败,并打印如下日志提醒你的 Receiver 需要公开:
BroadcastQueue: Exported Denial: sending Intent { act=com.example.demoapplication.RECEIVER flg=0x10 }, action: com.example.demoapplication.RECEIVER from com.example.tiramisu_demo (uid=10161)
due to receiver ProcessRecord{8e5f11c 16942:com.example.demoapplication/u0a158} (uid 10158) not specifying RECEIVER_EXPORTED
豁免
需要留意的是,系统级广播是受保护的,普通 App 没有权限发送。
所以只是监听系统广播的话,动态注册的 Receiver 无需指定上述 flag。即便指定了 RECEIVER_NOT_EXPORTED,和静态注册方式一致也能正常接收、不受影响。
适配办法
找到所有动态注册 Broadcast Receiver 的代码。如果监听的包含非系统广播,请根据是否公开给其他 App 的需要使用来添加 flag 的声明。
RECEIVER_EXPORTED
RECEIVER_NOT_EXPORTED
context.registerReceiver(sharedBroadcastReceiver, intentFilter,
RECEIVER_EXPORTED)
context.registerReceiver(privateBroadcastReceiver, intentFilter,
RECEIVER_NOT_EXPORTED)
来源:https://juejin.cn/post/7099450024525824037
猜你喜欢
- 一、File类的概述和构造方法public class Fileextends Objectimplements Serializable,
- 1. matlab的lp2lp函数的作用去归一化 H(s) 的分母2. matlab的lp2lp函数的使用方法[z, p, k]=butta
- 前段时间摸索了java调用matlab东西,不说学的有多深,也算有结果了,达到目的了。也即用java程序可以调用matlab中函数了。&nb
- 首先我们看看为什么添加Watch。ZooKeeper是用来协调(同步)分布式进程的服务,提供了一个简单高性能的协调内核,用户可以在此之上构建
- 1. 类的定义面向对象是通过类和对象去描述和代表万千事物对象的,首先我们需要知道如何去定义一个类。类的组成是由属性和行为两部分组成属性:在类
- 当我们使用swagger,进行接口测试,怕接口不安全,担心暴露。可采用两种方式1.环境权限配置对swagger文档配置只在测试环境可访问,生
- 组合模式是一种常见的设计模式(但我感觉有点复杂)也叫合成模式,有时又叫做部分-整体模式,主要是用来描述部分与整体的关系。个人理解:组合模式就
- 本文实例讲述了C#文件和字节流的转换方法。分享给大家供大家参考。具体实现方法如下:1、读取文件,并转换为字节流FileStream fs =
- WPF的ImageBrush是一个比较常见也比较复杂的笔刷,它继承自图块笔刷(TileBrush)。使用图块画笔绘制区域涉及以下三个组成部分
- Cookie1. 概念是服务器通知客户端保存键值对的一种技术。cookie 是 servlet(服务器) 发送到 Web 浏览器(客户端)的
- 1.Comparable前言,想要排序Student.有代码:import java.util.Arrays; class Stu
- 环境:apache-tomcat-8.5.15jdk1.8.0_172IDEA建立一个maven-webapp项目:Create New P
- 一、基本概念// 上下文对象 private Context context; public FileService(Context con
- 项目上线之后,如果日志打印的很模糊或者业务逻辑比较复杂,有时候无法定位具体的错误原因,因此可以通过IDEA远程代理进行Debug。线上的代码
- MANIFEST.MF打开Java的JAR文件我们经常可以看到文件中包含着一个META-INF目录, 这个目录下会有一些文件,其中必有一个M
- 同学们在开发过程中,经常需要查看程序与数据库之间的SQL语句,以便于调试和分析。本文将介绍如何在控制台中显示MyBatis的SQL语句,帮助
- ListView是android中最常用的控件之一。 在实际运用中往往会遇到一次性加载全部数据过多,需要分页加载增加程序运行效率! 本dem
- 1.场景介绍:开发过程中我们经常性的会用到许多的中间表,用于数据之间的对应和关联.这个时候我们关联最多的就是ID,我们在一张表中插入数据后级
- 一.简单介绍1.配置相关的依赖2.配置模式3写.mapper、controller、service4.配置yaml文件 配置mybatis全
- 如何打印GC日志排查问题在工作当中,有时候我们会需要打印GC的相关信息来定位问题。该如何做呢?先来看个示例public static voi