Android Intent安全那些事儿
前言¶
Intent是Android程序中不同组件传递数据的一种方式,翻译为意图,Intent既可以用在startActivity
方法中来启动Activity,也可以用在sendBroadcast
中来发送携带Intent的广播,甚至可以使用startService(Intent)
或者 bindService(Intent, ServiceConnection, int)
来和后台Service进行交互。总而言之,Intent是Android不同组件之间交互的一个桥梁,同时也能够在不同的应用之间进行数据的交互。其中,Intent又分为显示Intent和隐式Intent。
-
显式Intent:通过组件名指定启动的目标组件,比如
startActivity(new Intent(A.this,B.class));
每次启动的组件只有一个。这是一种较为安全的调用方式 -
隐式Intent:不指定组件名,而指定Intent的Action,Data或Category,当我们启动组件时,会去匹配
AndroidManifest.xml
相关组件的intent-filter
,逐一匹配出满足属性的组件,当不止一个满足时,会弹出一个让我们选择启动哪个的对话框。这种调用方式会间接导致很多问题
背景知识¶
Activity相关¶
让我们先来了解一下可能涉及到的函数接口
public void startActivityForResult (Intent intent, int requestCode)
这个方法本质上与public void startActivityForResult (Intent intent, int requestCode, Bundle options)
相同,用来在启动Activity结束后返回结果,其中第一个参数intent
是你需要发送的Intent,第二个参数requestCode
,当其大于或等于0时,Activity启动后的结果将被归还到onActivityResult
方法中;而当其小于0时,该方法本质上就等同于startActivity(Intent)
,即启动的Activity将不再被作为子Activity,不会返回数据。
public final void setResult (int resultCode, Intent data)
调用此方法可设置Activity返回调用方的result。第一个参数resultCode有三种常量,分别为RESULT_CANCELED
(值为0),RESULT_FIRST_USER
(值为1)和RESULT_OK
(值为-1)。第二个参数data
在Android 2.3以上版本可以被赋予Intent.FLAG_GRANT_READ_URI_PERMISSION
和/或Intent.FLAG_GRANT_WRITE_URI_PERMISSION
标志。这将授予接收结果的Activity对Intent中特定 URI 的访问权限,且访问将一直保留到Activity结束。
protected void onActivityResult(int requestCode, int resultCode, Intent data)
这个方法在启动的Activity退出时调用。其中第一个参数requestCode
用来提供给onActivityResult
确认数据是从哪个Activity返回的,其实就是在startActivityForResult
中设置的requestCode
。第二个参数resultCode
是由子Activity通过其setResult(Int, Intent)
方法返回的,值为setResult(int resultCode, Intent data)
的第一个参数resultCode
。
看完上面枯燥的介绍,相信还是有一点模糊的,光说不练假把式,下面举个例子,说明一下上面这几个函数的实际应用。
在如下所示的Demo中,FirstActivity
会通过startActivityForResult
方法启动SecondActivity
:
1 2 3 4 5 |
|
SecondActivity
收到intent后,会要求用户确认,若确认通过则通过setResult
将结果回传FirstActivity
:
1 2 3 4 5 6 |
|
FristActivity
可以通过onActivityResult
来接收返回的结果,并执行相应的操作:
1 2 3 4 5 6 7 |
|
以上就是这几个函数的一个简单的实践。
Content Provider相关¶
TODO: 补全
风险一:Intent重定向漏洞12345678¶
如果应用从不可信 Intent 的extras
字段中提取 Intent或部分信息,攻击者截取到Intent或部分信息后,主要有以下两种危害:
-
启动非预期的专用组件,利用敏感的参数来执行敏感操作
-
利用授予的 URI 权限窃取敏感文件或系统数据
利用点1:绕过原有代码执行逻辑或敏感数据泄露¶
第一种情况为,三方应用利用setResult
绕过原有的代码执行逻辑或者获取intent中携带的敏感数据。
在上文中,我们能够看见SecondActivity
中通过提取FirstActivity
中发送的intent,通过进一步处理,再将结果返回,我们查看SecondActivity
在AndroidManifest.xml
中的定义
1 2 3 4 5 6 7 8 |
|
发现intent-filter加入了特定的 action 和隐式 Intent 接收所必须的 android.intent.category.DEFAULT
,那么可以利用此处隐式发送 Intent, 造成 Intent 重定向。 首先,我们需要在三方应用新建一个拥有相同的 intent-filter 的Activity,这样三方应用就能够接收到 startActivityForResult
发送的 Intent(此处会匹配所有导出的且 intent-filter 相同的组件,并由用户选择,由于SecondActivity
为非导出组件,默认将会打开三方应用的Activity)。
创建日期: 2024-06-25