小白训练营|Android常用的两种跳转协议概述学习
前段时间,工作中经常会出现测试webview跳转的场景,所以对其中的跳转协议进行了简单的学习。
在android开发中,因为一个应用程序的功能往往很集中,但是又需要一些第三方应用拥有的扩展功能的支撑,这时候就会使用到android提供的跳转功能,跳转到某些第三方应用的展示页面。
若应用程序需要使用Webview打开一个第三方应用的页面时,有两种跳转方式比较常用,分别是:Scheme协议和Intent协议。
Scheme页面内跳转协议,是一种比较好的实现机制,开发者通过自定义的scheme协议,可以非常方便跳转app中的各个页面,它遵循 RFC 1808 (Relative Uniform Resource Locators) 标准,格式与一般URL的形式一样。
Scheme的几个使用场景
大致分为以下五种:
1. 通过小程序,利用Scheme协议打开原生app;
2. H5页面点击锚点,根据锚点具体跳转路径,使APP端跳转具体的页面;
3. APP端收到服务器端下发的PUSH通知栏消息,根据消息的点击跳转路径,跳转相关页面;
4. APP根据URL跳转到另外一个APP指定页面;
5. 通过短信息中的url打开原生app。
固定格式
若出现有端口的情况,形如:
http://www.baidu.com:80/yc?id=hello&name=cg
其中host(www.baidu.com)后的80为端口(port),将host+port组合起来的部分www.baidu.com:80又称之为域名(authority)。
需要注意的是:
在android中,除了scheme、authority是必须要有的,其它的path、query,它们都可以选择性的要或不要,但顺序不能变。
Scheme方式如何使用?
1、配置文件中定义必要元素
在AndroidManifest.xml中增加定义action、category和data标签,格式如下:
MainActivity包含多个<intent-filter>,第一个是正常的启动;第二个是通过Scheme方式启动,其本身也是隐式Intent调用的一种。
2、对跳转行为进行响应
在shouldOverrideUrlLoading处理自定义的scheme,进行必要的判断、过滤和异常捕获。
3 、在网页中根据url跳转
<a href="aaa://www.baidu.com:8888/ccc?id=1001">打开xxx</a>
Intent协议的介绍普遍较少,这是Android的一个很少人知道的特性,学习的时候可是着实费了一番功夫呢~
有这么一种场景,当用户登陆页面时启动应用程序,可以通过将iframe嵌入页面来实现页面跳转,如:
<iframe src="app://xxxpage"> </iframe>
这种方式在大部分android浏览器是适用的,但是Chrome浏览器25版本后功能有所不同,通过设置iframe中的src来跳转到自定义的uri就不生效了,所以作为替代就必须使用自定义的scheme实现用户手势启动app或者这次介绍的Intent协议。构造一个intent嵌入到页面中,或者通过在代码中实现Intent Extras传递其他信息,以提高启动应用程序方式的灵活性和兼容性。
Intent的格式
构造完成后形如:
intent://pointapp/app?appId=20000013&pwdType=ordinaryPassword&_t=111111#Intent;scheme=xxx;package=com.android.xxx;end
第二步往往是由浏览器本身去实现的,每个浏览器策略的不同就容易出现个别浏览器对于Intent协议处理不好的情况,隐患也就这么埋下了。
Intent协议代码实现中的参数解析
查看源码,可以看到Intent.parseUri(url,flag)中的三个flag值有一些不同。
flag1的格式
intent://host/path#Intent;scheme=xxxxx;package=com.xxx.app;end
在#Intent之前带的参数,需使用intent.getxxx()函数获取;
在#Intent之后带的参数,需使用intent.getData().getxxx()获取。
flag2的格式
android-app://{package}/{scheme}/{host}/{path}#Intent;action=xxx;S.xx=xx;end
注:scheme总是android-app
两种形式的区别:
1、配置上的区别
intent://形式一定要注册data的scheme用来和发起请求的scheme匹配对应;
android-app://形式可以不注册data的scheme,但是请求的时候要指定component;(即:"androidapp://com.xxx.xxx/#Intent;component=com.xxx.xxx/com.xxx.MainActivity;end";)
2、不同构造形式的action取值也不同
intent://形式默认的Action值是ACTION_VIEW;
app-android://形式如果只指定了包名的话,默认的Action值ACTION_MAIN,如果还有scheme和host则Action值为ACTION_VIEW,如果还指定了action的话,那Action值就是指定的action。
小发现:
在flag1参数构造中展示的S.[param],可以通过配置成特定的参数来解决无法启动应用程序,或者没有明确的跳转目的的情况,通过将其设置成:
S.browser_fallback_url=[encoded_full_url]
可以设置备用跳转网址,顾名思义,也就是当出现以上特殊情况时,将用户重定向到备用URL。是不是很方便呢~
Intent方式如何使用呢?
我们通过一张图来简单的解释下:
1、AndroidManifast.xml中的配置
2、响应Intent协议的行为
在shouldOverrideUrlLoading处理intent协议,进行两种形式的判断和必要的过滤策略。
3、如需获取intent协议中的参数
如果想要获取Intent协议传递的参数,那就需要在onCreate方法中使用getxxx()方法获取。
4、需要在网页中进行访问时
设置<a>标签中的href,形如<iframe>,以下为范例:
<a href=”intent://host/path#Intent;scheme=hansel;package=com.hansel.app;end”>
Scheme协议的攻击方式已经十分常见了,网上也介绍的比较全面,这里就不再过多赘述了,这里重点了解一下Intent协议。
Intent协议跳转和Intent程序内跳转解析的起点一样,都是从获取Intent对象开始,对于Intent对象的攻击比较常见也容易识别,从基础的本地拒绝服务,到成为组合漏洞的跳板导致薅羊毛或者提权的情况,不过现在随着开发人员的安全意识的提高,这类问题也发生的比较少了。
不过道高一尺,魔高一丈
又出现了针对Intent协议进行攻击的方式,因为配置中设置了android.intent.category.BROWSABLE,故而这种攻击手段非常依赖浏览器,一旦浏览器的保护措施做得不够,就会被当成桥梁实现Intent协议攻击,这种攻击非常难以发现,也不依靠本地代码,所有恶意代码都在网页中,无法通过一般的静态特征进行匹配,对人工发现的要求也比较高。
这种攻击不仅可以通过浏览器对手机上的其他应用发起攻击,还可以攻击浏览器本身进行访问,某些情况下甚至可以访问私有组件,或者一些cookie内容,不仅导致用户的信息泄露还导致浏览器的一些私有文件的泄露。
让我们用前人提供的一个小栗子作为参考,看看如何进行攻击。
某浏览器上的intent过滤策略完全缺失,但是它还支持Intent协议语法,所以我们就可以轻易的调用它的私有activity,调用方式形如:
通过上面的脚本,我们可以直接调起PointActivity。PointActivity会从intent中获取url,并开始加载cookies.html。
真实的攻击场景中,我们预先构造一个恶意网站,并让用户通过浏览器访问。这时在恶意页面中带上了获取cookie的代码,形如:
当PointActivity解析cookies文件时,就会获取到用户的cookies。
在这庞大的互联网知识世界中,小编发现了一个比较好的漏洞缓解方案,给各位读者作为参考:
参考文章:
https://www.jianshu.com/p/1e6a7750bfa1
https://www.jianshu.com/p/7b09cbac1df4
其他案例:
https://blog.csdn.net/l173864930/article/details/36951805