Перенаправление намерения

Категория OWASP: MASVS-PLATFORM: Взаимодействие платформ

Обзор

Перенаправление намерений происходит, когда злоумышленник может частично или полностью контролировать содержимое намерения, используемого для запуска нового компонента в контексте уязвимого приложения.

Интент, используемый для запуска нового компонента, может быть задан несколькими способами, чаще всего либо в виде сериализованного интента в поле extras , либо в виде маршалированного значения в строку и последующего анализа. Частичный контроль параметров также может привести к тому же результату.

Влияние

Последствия могут быть различными. Злоумышленник может выполнить внутренние функции уязвимого приложения или получить доступ к закрытым компонентам, таким как неэкспортируемые объекты ContentProvider.

Меры по смягчению последствий

В целом, не следует раскрывать функции, связанные с перенаправлением вложенных интентов. В случаях, когда это неизбежно, применяйте следующие методы смягчения последствий:

  • Необходимо надлежащим образом очистить и обработать содержащуюся в пакете информацию. Важно помнить о необходимости проверить или снять флаги ( FLAG_GRANT_READ_URI_PERMISSION, FLAG_GRANT_WRITE_URI_PERMISSION, FLAG_GRANT_PERSISTABLE_URI_PERMISSION, and FLAG_GRANT_PREFIX_URI_PERMISSION ), а также проверить, куда перенаправляется Intent. IntentSanitizer может помочь в этом процессе.
  • Используйте объекты PendingIntent . Это предотвратит экспорт вашего компонента и сделает целевой объект действия неизменяемым.

Приложения могут проверять, куда перенаправляется намерение, используя такие методы, как ResolveActivity :

Котлин

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 , применяя логику, аналогичную следующей:

Котлин

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);

Защита по умолчанию

В Android 16 по умолчанию внедрено решение для усиления безопасности в отношении уязвимостей, связанных с перенаправлением Intent . В большинстве случаев приложения, использующие Intent, обычно не испытывают проблем с совместимостью.

Отказаться от обработки перенаправлений Intent

В Android 16 представлен новый API, позволяющий приложениям отключать защиту при запуске. Это может быть необходимо в отдельных случаях, когда поведение системы безопасности по умолчанию мешает корректному использованию приложений.

В Android 16 можно отключить защиту, используя метод removeLaunchSecurityProtection() объекта Intent . Например:

val i = intent
val iSublevel: Intent? = i.getParcelableExtra("sub_intent")
iSublevel?.removeLaunchSecurityProtection() // Opt out from hardening
iSublevel?.let { startActivity(it) }

Распространенные ошибки

  • Проверка, возвращает ли функция getCallingActivity() ненулевое значение. Вредоносные приложения могут передавать этой функции нулевое значение.
  • Предполагается, что checkCallingPermission() работает во всех контекстах или что метод выбрасывает исключение, когда фактически возвращает целое число.

Функции отладки

Для приложений, ориентированных на Android 12 (уровень API 31) или выше, можно включить функцию отладки , которая в некоторых случаях помогает определить, выполняет ли ваше приложение небезопасный запуск намерения.

Если ваше приложение выполняет оба следующих действия, система обнаруживает небезопасный запуск интента, и происходит нарушение StrictMode :

  • Ваше приложение отделяет вложенный интент от дополнительных данных доставленного интента.
  • Ваше приложение немедленно запускает компонент приложения, используя этот вложенный интент, например, передавая интент в startActivity() , startService() или bindService() .

Ресурсы