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

Категория OWASP: MASVS-ПЛАТФОРМА: Взаимодействие платформы

Обзор

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

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

Влияние

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

Смягчения

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

  • Надлежащим образом очистите связанную информацию. Важно не забывать проверять или снимать флаги ( FLAG_GRANT_READ_URI_PERMISSION, FLAG_GRANT_WRITE_URI_PERMISSION, FLAG_GRANT_PERSISTABLE_URI_PERMISSION, and FLAG_GRANT_PREFIX_URI_PERMISSION ), а также проверять, куда перенаправляется намерение. 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)
}

Ява

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)

Ява

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

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

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

Отладка функций

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

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

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

Ресурсы