Отложенные интенты

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

Обзор

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

Риск: изменяемые отложенные интенты

Намерение PendingIntent может быть изменяемым. Это значит, что внутреннее намерение, определяющее действие, может быть обновлено приложением B в соответствии с логикой, описанной в документации fillIn(). Другими словами, вредоносное приложение может изменить незаполненные поля PendingIntent и получить доступ к неэкспортируемым компонентам уязвимого приложения.

Влияние

Последствия уязвимости зависят от того, как реализована целевая неэкспортируемая функция приложения.

Предотвращение атак

Общие

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

Kotlin

val intent = Intent(intentAction)

// Or other component setting APIs e.g. setComponent, setClass
intent.setClassName(packageName, className)

PendingIntent pendingIntent =
    PendingIntent.getActivity(
        context,
        /* requestCode = */ 0,
        intent, /* flags = */ PendingIntent.FLAG_IMMUTABLE
    )

Java

Intent intent = new Intent(intentAction);

// Or other component setting APIs e.g. setComponent, setClass
intent.setClassName(packageName, className);

PendingIntent pendingIntent =
        PendingIntent.getActivity(
            getContext(),
            /* requestCode= */ 0,
            intent, /* flags= */ 0);

Флаг IMMUTABLE

Если ваше приложение поддерживает Android 6 (уровень API 23) или более поздние версии, укажите изменяемость. Например, вы можете использовать FLAG_IMMUTABLE, чтобы предотвратить заполнение пустых полей вредоносным приложением:

Kotlin

val pendingIntent =
    PendingIntent.getActivity(
        context,
        /* requestCode = */ 0,
        Intent(intentAction),
        PendingIntent.FLAG_IMMUTABLE)

Java

PendingIntent pendingIntent =
        PendingIntent.getActivity(
            getContext(),
            /* requestCode= */ 0,
            new Intent(intentAction),
            PendingIntent.FLAG_IMMUTABLE);

В Android 11 (уровень API 30) и более поздних версиях необходимо указывать, какие поля должны быть изменяемыми. Это позволяет снизить риск возникновения уязвимостей такого типа.

Ресурсы


Риск: повторное воспроизведение отложенных интентов

Объект PendingIntent можно воспроизвести повторно, если не установлен флаг FLAG_ONE_SHOT. Важно использовать FLAG_ONE_SHOT, чтобы избежать атак повторного воспроизведения (выполнения действий, которые не должны повторяться).

Влияние

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

Предотвращение атак

Если отложенный интент не должен запускаться несколько раз, используйте флаг FLAG_ONE_SHOT, чтобы избежать атак с повторной передачей.

Kotlin

val pendingIntent =
      PendingIntent.getActivity(
          context,
          /* requestCode = */ 0,
          Intent(intentAction),
          PendingIntent.FLAG_IMMUTABLE or PendingIntent.FLAG_ONE_SHOT)

Java

PendingIntent pendingIntent =
        PendingIntent.getActivity(
            getContext(),
            /* requestCode= */ 0,
            new Intent(intentAction),
            PendingIntent.FLAG_IMMUTABLE | PendingIntent.FLAG_ONE_SHOT);

Ресурсы


Ресурсы