4.7 使用可浏览的意图
原书:Android Application Secure Design/Secure Coding Guidebook 译者:飞龙 协议:CC BY-NC-SA 4.0
Android 应用可以设计为从浏览器启动,并对应网页链接。 这个功能被称为“可浏览的意图”。 通过在清单文件中指定 URI 模式,应用将响应具有其 URI 模式的链接转移(用户点击等),并且应用以链接作为参数启动。
此外,使用 URI 模式从浏览器启动相应应用的方法不仅支持 Android,也支持 iOS 和其他平台,这通常用于 Web 应用与外部应用之间的链接等。例如, 在 Twitter 应用或 Facebook 应用中定义了以下 URI 模式,并且在 Android 和 iOS 中从浏览器启动相应的应用。
表 4.7-1
URL 模式 | 相应应用 |
---|---|
fb:// | |
twitter:// |
考虑到联动性和便利性,功能似乎非常方便,但存在一些风险,即该功能被恶意第三方滥用。 可以假设的是,它们滥用应用功能,通过准备一个恶意网站,它的链接的 URL 具有不正确的参数,或者它们通过欺骗智能手机用户安装恶意软件,它包含相同的 URI 模式,来获取包含在 URL 中的信息。 使用“可浏览的意图”来对付这些风险时有一些要注意的地方。
4.7.1 示例代码
使用“可浏览的意图”的应用的示例代码如下:
要点:
1) (网页侧)不得包含敏感信息。
2) 仔细和安全地处理 URL 参数。
Starter.html
代码语言:javascript复制<html>
<body>
<!-- *** POINT 1 *** Sensitive information must not be included -->
<!-- Character strings to be passed as URL parameter, should be UTF-8 and URI encoded. -->
<a href="secure://jssec?user=user_id"> Login </a>
</body>
</html>
AndroidManifest.xml
代码语言:javascript复制<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/
<application
android:icon="@drawable/ic_launcher"
android:label="@string/app_name"
android:allowBackup="false" >
<activity
android:name=".BrowsableIntentActivity"
android:label="@string/title_activity_browsable_intent"
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.VIEW" />
// Accept implicit Intent
<category android:name="android.intent.category.DEFAULT" />
// Accept Browsable intent
<category android:name="android.intent.category.BROWSABLE" />
// Accept URI 'secure://jssec'
<data android:scheme="secure" android:host="jssec"/>
</intent-filter>
</activity>
</application>
</manifest>
BrowsableIntentActivity.java
代码语言:javascript复制package org.jssec.android.browsableintent;
import android.app.Activity;
import android.content.Intent;
import android.net.Uri;
import android.os.Bundle;
import android.widget.TextView;
public class BrowsableIntentActivity extends Activity {
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_browsable_intent);
Intent intent = getIntent();
Uri uri = intent.getData();
if (uri != null) {
// Get UserID which is passed by URI parameter
// *** POINT 2 *** Handle the URL parameter carefully and securely.
// Omitted, since this is a sample. Please refer to "3.2 Handling Input Data Carefully and Securely."
String userID = "User ID = " uri.getQueryParameter("user");
TextView tv = (TextView)findViewById(R.id.text_userid);
tv.setText(userID);
}
}
}
4.7.2 规则书
使用“可浏览的意图”时,需要遵循以下规则:
4.7.2.1 (网页端)敏感信息不得包含在相应链接的参数中(必需)
当点击浏览器中的链接时,会发出一个意图,该意图的数据中有 URL 值(可以通过Intent#getData
获取),并且带有相应意图过滤器的应用,从 Android 系统启动。
此时,当几个应用设置意图过滤器来接收相同的 URI 模式时,应用选择对话框将显示,与隐式意图正常启动相同,并启动用户选择的应用。 如果应用选择对话框中列出了恶意软件,则用户可能会错误地启动恶意软件,并将 URL 中的参数发送到恶意软件。
如上所述,需要避免直接在 URL 参数中包含敏感信息,因为它用于创建一般网页链接,所有包含在网页链接 URL 中的参数都可以提供给恶意软件。
用户 ID 和密码包含在 URL 中的例子:
代码语言:javascript复制insecure://sample/login?userID=12345&password=abcdef
此外,即使 URL 参数仅包含非敏感内容,如用户ID,在由’可浏览的意图’启动后,在应用中输入密码时,用户可能会启动恶意软件并向其输入密码。所以应该考虑,一些规范,例如整个登录过程,在应用端完成。 在设计应用时必须记住它,并且由’可浏览的意图’启动应用,等同于由隐式意图启动,并且不保证启动了有效的应用。
4.7.2.2 小心和安全地处理 URL 参数(必需)
发送给应用的 URL 参数,并不总是来自合法的 Web 页面,因为匹配 URI 模式链接不仅可以由开发者生成,也可以由任何人生成。 另外,没有方法可以验证 URL 参数是否从有效网页发送。
因此,在使用 URL 参数之前,有必要验证 URL 参数的安全性,例如,检查是否包含意外值。