Intent in attesa

Categoria OWASP: MASVS-PLATFORM: Interazione con la piattaforma

Panoramica

Un PendingIntent è un riferimento a un token gestito dal sistema. L'applicazione A può passare un PendingIntent all'applicazione B per consentire a quest'ultima di eseguire azioni predefinite per conto dell'applicazione A, indipendentemente dal fatto che l'applicazione A sia ancora in esecuzione.

Rischio: intent in attesa mutabili

Un PendingIntent può essere mutabile, il che significa che l'intent interno che specifica l'azione può essere aggiornato dall'applicazione B seguendo la logica descritta nella documentazione di fillIn(). In altre parole, i campi non compilati di un PendingIntent possono essere modificati da un'app dannosa e consentire l'accesso a componenti dell'applicazione vulnerabile altrimenti non esportati.

Impatto

L'impatto di questa vulnerabilità varia a seconda dell'implementazione della funzionalità non esportata dell'app scelta come target.

Mitigazioni

Generali

Assicurati che l'azione, il componente e il pacchetto siano impostati per evitare le vulnerabilità peggiori:

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

Flag IMMUTABLE

Se la tua app ha come target Android 6 (livello API 23) o versioni successive, specifica la mutabilità. Ad esempio, puoi utilizzare FLAG_IMMUTABLE per impedire che un'applicazione dannosa compili i campi vuoti:

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

Su Android 11 (livello API 30) e versioni successive, devi specificare quali campi rendere mutabili, il che riduce le vulnerabilità accidentali di questo tipo.

Risorse


Rischio: riproduzione di intent in attesa

Un PendingIntent può essere riprodotto a meno che non sia impostato il flag FLAG_ONE_SHOT. È importante utilizzare FLAG_ONE_SHOT per evitare attacchi di replay (esecuzione di azioni che non devono essere ripetibili).

Impatto

L'impatto di questa vulnerabilità varia a seconda dell'implementazione dell'estremità ricevente dell'intent. Un'app dannosa che sfrutta un PendingIntent creato senza impostare il flag FLAG_ONE_SHOT potrebbe acquisire e riutilizzare l'intent per ripetere azioni che dovrebbero essere eseguite una sola volta.

Mitigazioni

Gli intent in attesa che non devono essere attivati più volte devono utilizzare il flag FLAG_ONE_SHOT per evitare attacchi di 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);

Risorse


Risorse