本文的目标受众是其应用存在 Intent 重定向漏洞的开发者。
问题说明
您的一个或多个应用中存在 Intent 重定向问题,恶意应用可利用该漏洞访问专用应用组件或文件。请阅读下面的详细步骤,然后解决您的应用存在的问题。在 Play 管理中心内显示的最后期限过后,系统会将所有包含未修复安全漏洞的应用从 Google Play 下架。
需要采取的行动
- 登录您的 Play 管理中心,然后转到“提醒”部分,查看受影响的应用以及解决这些问题的最后期限。
- 按照下文中强调的步骤更新受影响的应用。
- 提交受影响应用的更新版本。
重新提交后,我们会重新审核您的应用。审核过程可能需要几个小时才能完成。如果应用通过审核并成功发布,便无需进一步操作。如果应用未通过审核,则新版应用将无法发布,您会收到电子邮件通知。
更多详情
使用不可信 Intent 启动组件(例如,通过调用 startActivity),或返回数据(例如,通过调用setResult)会造成危险,而且可能让恶意应用造成以下问题:
- 从您的应用中窃取敏感文件或系统数据(例如短信)
- 利用中毒的参数启动应用的专用组件。
您的应用不应在未经验证或消除这些 Intent 的情况下,对不可信 Intent 调用 startActivity、startService、sendBroadcast 或 setResult。
我们建议您通过下列方法之一防范此漏洞:
方法 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
- 不会被发送到您的应用的任何专用组件,并且
- 不会被发送到外部应用的组件。如果重定向的目标是外部应用,请确保该 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”标签)。有关您需要采取哪些步骤来解决此问题的说明,请与我们的开发者支持团队联系。