Oczekujące intencje

Kategoria OWASP: MASVS-PLATFORM: Platform Interaction (Interakcja z platformą)

Przegląd

A PendingIntent to odniesienie do tokena utrzymywanego przez system. Aplikacja A może przekazać intencję PendingIntent do aplikacji B, aby umożliwić jej wykonywanie predefiniowanych działań w imieniu aplikacji A, niezależnie od tego, czy aplikacja A jest nadal aktywna.

Ryzyko: zmienne intencje PendingIntent

Intencja PendingIntent może być zmienna, co oznacza, że wewnętrzna intencja określająca działanie może zostać zaktualizowana przez aplikację B zgodnie z logiką opisaną w fillIn() dokumentacji. Innymi słowy, nieuzupełnione pola intencji PendingIntent mogą zostać zmodyfikowane przez złośliwą aplikację, co umożliwi dostęp do nieeksportowanych składników podatnej na ataki aplikacji.

Wpływ

Wpływ tej luki w zabezpieczeniach zależy od implementacji nieeksportowanej funkcji aplikacji.

Środki zaradcze

Ogólne

Aby uniknąć najgorszych luk w zabezpieczeniach, upewnij się, że ustawione są działanie, komponent i pakiet:

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

Flaga IMMUTABLE

Jeśli Twoja aplikacja jest kierowana na Androida 6 (poziom API 23) lub nowszego, określ zmienność. Możesz to zrobić na przykład za pomocą FLAG_IMMUTABLE, aby uniemożliwić złośliwej aplikacji wypełnianie nieuzupełnionych pól:

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

W Androidzie 11 (poziom API 30) i nowszych wersjach musisz określić, które pola mają być zmienne, co zmniejsza ryzyko przypadkowych luk w zabezpieczeniach tego typu.

Zasoby


Ryzyko: ponowne odtwarzanie intencji PendingIntent

Intencję PendingIntent można odtworzyć ponownie, chyba że ustawiona jest flaga FLAG_ONE_SHOT. Aby uniknąć ataków typu replay (wykonywania działań, które nie powinny być powtarzalne), należy używać flagi FLAG_ONE_SHOT.

Wpływ

Wpływ tej luki w zabezpieczeniach zależy od implementacji odbiorcy intencji. Złośliwa aplikacja wykorzystująca intencję PendingIntent utworzoną bez ustawienia flagi FLAG_ONE_SHOT może przechwycić i ponownie wykorzystać intencję do powtarzania działań, które powinny być wykonywane tylko raz.

Środki zaradcze

Intencje PendingIntent, które nie mają być uruchamiane wielokrotnie, powinny używać flagi FLAG_ONE_SHOT, aby uniknąć ataków typu replay.

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

Zasoby


Zasoby