intent 重定向

OWASP 类别MASVS-PLATFORM:平台互动

概览

当攻击者部分或完全控制用于在存在漏洞的应用上下文中启动新组件的 intent 内容时,就会出现 intent 重定向问题。

可以通过多种方式提供用于启动新组件的 intent,最常见的方式是在 extras 字段中表示为序列化 intent,或者封送到字符串中并进行解析。即使是部分控制参数,也会导致相同的结果。

影响

影响可能不尽相同。攻击者可能会在存在漏洞的应用中执行内部功能,或者可能会访问专用组件,例如不支持导出的 ContentProvider 对象。

缓解措施

一般措施

一般来说,不要公开与重定向嵌套 intent 相关的功能。如果不可避免,请采用以下缓解方法:

  • 适当地清理捆绑信息。请务必检查或清除标志 (GRANT_URI_PERMISSIONS),并检查 intent 被重定向到的位置。您可以借助 IntentSanitizer 完成此过程。
  • 使用 PendingIntent 对象。这样可以阻止您的组件被导出,使目标操作 intent 不可变。

应用可以使用 ResolveActivity 等方法检查 intent 被重定向到的位置:

Kotlin

val intent = getIntent()
// Get the component name of the nested intent.
val forward = intent.getParcelableExtra<Parcelable>("key") as Intent
val name: ComponentName = forward.resolveActivity(packageManager)
// Check that the package name and class name contain the expected values.
if (name.packagename == "safe_package" && name.className == "safe_class") {
    // Redirect the nested intent.
    startActivity(forward)
}

Java

Intent intent = getIntent()
// Get the component name of the nested intent.
Intent forward = (Intent) intent.getParcelableExtra("key");
ComponentName name = forward.resolveActivity(getPackageManager());
// Check that the package name and class name contain the expected values.
if (name.getPackageName().equals("safe_package") &&
        name.getClassName().equals("safe_class")) {
    // Redirect the nested intent.
    startActivity(forward);
}

应用可以使用 IntentSanitizer,其逻辑类似于:

Kotlin

val intent = IntentSanitizer.Builder()
     .allowComponent("com.example.ActivityA")
     .allowData("com.example")
     .allowType("text/plain")
     .build()
     .sanitizeByThrowing(intent)

Java

Intent intent = new  IntentSanitizer.Builder()
     .allowComponent("com.example.ActivityA")
     .allowData("com.example")
     .allowType("text/plain")
     .build()
     .sanitizeByThrowing(intent);

常见错误

  • 检查 getCallingActivity() 返回的是否为非 null 值。恶意应用可以为此函数提供 null 值。
  • 假定 checkCallingPermission() 适用于所有上下文,或者该方法会在实际返回整数时抛出异常。

调试功能

对于以 Android 12(API 级别 31)或更高版本为目标平台的应用,您可以启用调试功能,在某些情况下,此功能可帮助您检测应用是否以不安全的方式启动 intent。

如果您的应用同时执行以下两项操作,系统会检测到不安全的 intent 启动,并且 StrictMode 会检测到违规事件:

  • 您的应用从已传递的 intent 的 extra 中解封嵌套 intent。
  • 您的应用立即使用该嵌套 intent 启动应用组件,例如将 intent 传递给 startActivity()startService()bindService()

资源

  • 注意:当 JavaScript 处于关闭状态时,系统会显示链接文字
  • 待处理 intent