4.7 使用可浏览的意图

Android 应用可以设计为从浏览器启动,并对应网页链接。 这个功能被称为“可浏览的意图”。 通过在清单文件中指定 URI 模式,应用将响应具有其 URI 模式的链接转移(用户点击等),并且应用以链接作为参数启动。

此外,使用 URI 模式从浏览器启动相应应用的方法不仅支持 Android,也支持 iOS 和其他平台,这通常用于 Web 应用与外部应用之间的链接等。例如, 在 Twitter 应用或 Facebook 应用中定义了以下 URI 模式,并且在 Android 和 iOS 中从浏览器启动相应的应用。

表 4.7-1

URL 模式 相应应用
fb:// Facebook
twitter:// Twitter

考虑到联动性和便利性,功能似乎非常方便,但存在一些风险,即该功能被恶意第三方滥用。 可以假设的是,它们滥用应用功能,通过准备一个恶意网站,它的链接的 URL 具有不正确的参数,或者它们通过欺骗智能手机用户安装恶意软件,它包含相同的 URI 模式,来获取包含在 URL 中的信息。 使用“可浏览的意图”来对付这些风险时有一些要注意的地方。

4.7.1 示例代码

使用“可浏览的意图”的应用的示例代码如下:

要点:

  1. (网页侧)不得包含敏感信息。

  2. 仔细和安全地处理 URL 参数。

Starter.html

  1. <html>
  2. <body>
  3. <!-- *** POINT 1 *** Sensitive information must not be included -->
  4. <!-- Character strings to be passed as URL parameter, should be UTF-8 and URI encoded. -->
  5. <a href="secure://jssec?user=user_id"> Login </a>
  6. </body>
  7. </html>

AndroidManifest.xml

  1. <?xml version="1.0" encoding="utf-8"?>
  2. <manifest xmlns:android="http://schemas.android.com/
  3. <application
  4. android:icon="@drawable/ic_launcher"
  5. android:label="@string/app_name"
  6. android:allowBackup="false" >
  7. <activity
  8. android:name=".BrowsableIntentActivity"
  9. android:label="@string/title_activity_browsable_intent"
  10. android:exported="true" >
  11. <intent-filter>
  12. <action android:name="android.intent.action.MAIN" />
  13. <category android:name="android.intent.category.LAUNCHER" />
  14. </intent-filter>
  15. <intent-filter>
  16. <action android:name="android.intent.action.VIEW" />
  17. // Accept implicit Intent
  18. <category android:name="android.intent.category.DEFAULT" />
  19. // Accept Browsable intent
  20. <category android:name="android.intent.category.BROWSABLE" />
  21. // Accept URI 'secure://jssec'
  22. <data android:scheme="secure" android:host="jssec"/>
  23. </intent-filter>
  24. </activity>
  25. </application>
  26. </manifest>

BrowsableIntentActivity.java

  1. package org.jssec.android.browsableintent;
  2. import android.app.Activity;
  3. import android.content.Intent;
  4. import android.net.Uri;
  5. import android.os.Bundle;
  6. import android.widget.TextView;
  7. public class BrowsableIntentActivity extends Activity {
  8. @Override
  9. public void onCreate(Bundle savedInstanceState) {
  10. super.onCreate(savedInstanceState);
  11. setContentView(R.layout.activity_browsable_intent);
  12. Intent intent = getIntent();
  13. Uri uri = intent.getData();
  14. if (uri != null) {
  15. // Get UserID which is passed by URI parameter
  16. // *** POINT 2 *** Handle the URL parameter carefully and securely.
  17. // Omitted, since this is a sample. Please refer to "3.2 Handling Input Data Carefully and Securely."
  18. String userID = "User ID = " + uri.getQueryParameter("user");
  19. TextView tv = (TextView)findViewById(R.id.text_userid);
  20. tv.setText(userID);
  21. }
  22. }
  23. }

4.7.2 规则书

使用“可浏览的意图”时,需要遵循以下规则:

4.7.2.1 (网页端)敏感信息不得包含在相应链接的参数中(必需)

当点击浏览器中的链接时,会发出一个意图,该意图的数据中有 URL 值(可以通过Intent#getData获取),并且带有相应意图过滤器的应用,从 Android 系统启动。

此时,当几个应用设置意图过滤器来接收相同的 URI 模式时,应用选择对话框将显示,与隐式意图正常启动相同,并启动用户选择的应用。 如果应用选择对话框中列出了恶意软件,则用户可能会错误地启动恶意软件,并将 URL 中的参数发送到恶意软件。

如上所述,需要避免直接在 URL 参数中包含敏感信息,因为它用于创建一般网页链接,所有包含在网页链接 URL 中的参数都可以提供给恶意软件。

用户 ID 和密码包含在 URL 中的例子:

  1. insecure://sample/login?userID=12345&password=abcdef

此外,即使 URL 参数仅包含非敏感内容,如用户ID,在由’可浏览的意图’启动后,在应用中输入密码时,用户可能会启动恶意软件并向其输入密码。所以应该考虑,一些规范,例如整个登录过程,在应用端完成。 在设计应用时必须记住它,并且由’可浏览的意图’启动应用,等同于由隐式意图启动,并且不保证启动了有效的应用。

4.7.2.2 小心和安全地处理 URL 参数(必需)

发送给应用的 URL 参数,并不总是来自合法的 Web 页面,因为匹配 URI 模式链接不仅可以由开发者生成,也可以由任何人生成。 另外,没有方法可以验证 URL 参数是否从有效网页发送。

因此,在使用 URL 参数之前,有必要验证 URL 参数的安全性,例如,检查是否包含意外值。