Intent tertunda

Kategori OWASP: MASVS-PLATFORM: Platform Interaction

Ringkasan

PendingIntent adalah referensi ke token yang dikelola oleh sistem. Aplikasi A dapat meneruskan PendingIntent ke aplikasi B agar aplikasi B dapat mengeksekusi tindakan yang telah ditetapkan atas nama aplikasi A; terlepas dari apakah aplikasi A masih aktif.

Risiko: Intent Tertunda yang Dapat Diubah

PendingIntent dapat berubah, yang berarti intent internal yang menentukan tindakan dapat diupdate oleh aplikasi B dengan mengikuti logika yang dijelaskan dalam dokumentasi fillIn(). Dengan kata lain, kolom PendingIntent yang tidak terisi dapat diubah oleh aplikasi berbahaya dan memungkinkan akses ke komponen aplikasi rentan yang tidak diekspor.

Dampak

Dampak kerentanan ini bervariasi, bergantung pada implementasi fungsi aplikasi yang tidak diekspor yang ditargetkan.

Mitigasi

Umum

Pastikan tindakan, komponen, dan paket ditetapkan untuk menghindari kerentanan terburuk:

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

Tandai IMMUTABLE

Jika aplikasi Anda menargetkan Android 6 (API level 23) atau yang lebih tinggi, tentukan mutabilitas. Misalnya, hal ini dapat dilakukan dengan menggunakan FLAG_IMMUTABLE untuk mencegah kolom yang tidak terisi agar tidak diisi oleh aplikasi berbahaya:

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

Di Android 11 (API level 30) dan lebih tinggi, Anda harus menentukan kolom mana yang akan dapat diubah, sehingga mengurangi kerentanan yang tidak disengaja dari jenis ini.

Referensi


Risiko: Mereplay Intent yang Tertunda

PendingIntent dapat direplay, kecuali jika tanda FLAG_ONE_SHOT ditetapkan. FLAG_ONE_SHOT harus digunakan untuk menghindari serangan replay (melakukan tindakan yang tidak boleh berulang).

Dampak

Dampak kerentanan ini bervariasi, bergantung pada implementasi akhir penerimaan intent. Aplikasi berbahaya yang mengeksploitasi PendingIntent yang dibuat tanpa menyetel tanda FLAG_ONE_SHOT dapat menangkap dan menggunakan kembali intent untuk mengulangi tindakan yang seharusnya hanya dapat dilakukan sekali.

Mitigasi

Intent tertunda yang tidak dimaksudkan untuk diaktifkan beberapa kali harus menggunakan tanda FLAG_ONE_SHOT untuk menghindari serangan 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);

Referensi


Referensi