针对 Intent 重定向漏洞的修复方法

本文的目标受众是其应用存在 Intent 重定向漏洞的开发者。

问题说明

您的一个或多个应用中存在 Intent 重定向问题,恶意应用可利用该漏洞访问专用应用组件或文件。请阅读下面的详细步骤,然后解决您的应用存在的问题。在 Play 管理中心内显示的最后期限过后,系统会将所有包含未修复安全漏洞的应用从 Google Play 下架。

需要采取的行动

  1. 登录您的 Play 管理中心,然后转到“提醒”部分,查看受影响的应用以及解决这些问题的最后期限。
  2. 按照下文中强调的步骤更新受影响的应用。
  3. 提交受影响应用的更新版本。

重新提交后,我们会重新审核您的应用。审核过程可能需要几个小时才能完成。如果应用通过审核并成功发布,便无需进一步操作。如果应用未通过审核,则新版应用将无法发布,您会收到电子邮件通知。

更多详情

使用不可信 Intent 启动组件(例如,通过调用 startActivity),或返回数据(例如,通过调用setResult)会造成危险,而且可能让恶意应用造成以下问题:

  1. 从您的应用中窃取敏感文件或系统数据(例如短信)
  2. 利用中毒的参数启动应用的专用组件。

您的应用不应在未经验证或消除这些 Intent 的情况下,对不可信 Intent 调用 startActivitystartServicesendBroadcastsetResult

我们建议您通过下列方法之一防范此漏洞:

方法 1:将受影响的应用组件(提取的 Intent 从其中进行重定向)设为专用组件。

如果受影响的应用组件不需要接收来自其他应用的 Intent,您可以将此应用组件设为专用组件,只需在清单中设置 android:exported=”false” 即可。

方法 2:确保提取的 Intent 来自可信的来源。

您可以使用 getCallingActivity 等方法来验证源 Activity 是否可信。例如:

 // 检查源 Activity 是否来自可信软件包
 if (getCallingActivity().getPackageName().equals(“known”)) {
   Intent intent = getIntent();
   // 提取嵌套的 Intent
   Intent forward = (Intent) intent.getParcelableExtra(“key”);
   // 重定向嵌套的 Intent
   startActivity(forward);
 }

注意:

  • 检查 getCallingActivity() 是否返回非 null 值并不足以防范此漏洞。恶意应用可以为此函数提供 null 值。
  • 对于 Google Play 服务 SMS Retriever Auth,通过使用 SEND_PERMISSION 保护广播接收器,可确保 Intent 来自 Play 服务。

方法 3:确保要重定向的 Intent 安全无害。

您应该验证重定向的 Intent,确保该 Intent

  1. 不会被发送到您的应用的任何专用组件,并且
  2. 不会被发送到外部应用的组件。如果重定向的目标是外部应用,请确保该 Intent 不会向您的应用的某个专用内容提供方或系统数据授予 URI 权限

在重定向 Intent 之前,应用可以先使用 resolveActivity 等方法检查将使用哪个组件来处理该 Intent。例如:

 Intent intent = getIntent();
 // 提取嵌套的 Intent
 Intent forward = (Intent) intent.getParcelableExtra(“key”);
 // 获取组件名称
 ComponentName name = forward.resolveActivity(getPackageManager());
 // 检查软件包名称和类名称是否与预期相符
 if (name.getPackageName().equals(“safe_package”) &&
     name.getClassName().equals(“safe_class”)) {
   // 重定向嵌套的 Intent
   startActivity(forward);
 }

应用可以使用 getFlags 等方法来检查 Intent 是否会授予 URI 权限。例如:

 // 提取嵌套的 Intent
 Intent forward = (Intent) intent.getParcelableExtra(“key”);
 // 获取标记
 int flags = forward.getFlags();
 // 检查嵌套的 Intent 是否不会授予 URI 权限
 if ((flags & Intent.FLAG_GRANT_READ_URI_PERMISSION == 0) &&
     (flags & Intent.FLAG_GRANT_WRITE_URI_PERMISSION == 0)) {
   // 重定向嵌套的 Intent
   startActivity(forward);
 }

应用还可以使用 removeFlags 撤消 URI 权限的授予。例如:

 // 不可信 Intent
Intent intent = getIntent');
 // 移除不可信 Intent 中授予的 URI 权限
intent.removeFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
intent.removeFlags(Intent) FLAG_GRANT_WRITE_URI_PERMISSION);
 // 传递不可信 Intent
 setResult(intent);

了解提醒信息及选择防范方法

Play 管理中心提醒会报告您的应用使用不可信 Intent 调用 startActivity、startActivityForResult、startService、sendBroadcast 或 setResult 的位置。为了更好地了解哪种防范方法最合适,请追溯并查看方法调用方,以找出不可信 Intent 的来源。例如,若考虑使用第 1 种防范方法,应通过追溯来确定要设为专用组件的组件。

我们随时为您提供帮助

如果您有关于此漏洞的技术问题,可以在 Stack Overflow 上发帖咨询(使用“android-security”标签)。有关您需要采取哪些步骤来解决此问题的说明,请与我们的开发者支持团队联系。

该内容对您有帮助吗?

您有什么改进建议?
false
主菜单
17499218408808160683
true
搜索支持中心
true
true
true
true
true
5016068
false
false