Penerima siaran tidak aman

Kategori OWASP: MASVS-PLATFORM: Interaksi Platform

Ringkasan

Penerima siaran yang diterapkan dengan tidak semestinya dapat memungkinkan penyerang mengirim intent berbahaya untuk membuat aplikasi yang rentan melakukan tindakan yang tidak ditujukan untuk pemanggil eksternal.

Kerentanan ini umumnya mengacu pada instance saat penerima siaran diekspor secara tidak sengaja, baik dengan menetapkan android:exported="true" di AndroidManifest atau dengan membuat penerima siaran secara terprogram yang membuat penerima bersifat publik secara default. Jika penerima tidak berisi filter intent, nilai defaultnya adalah "false", tetapi jika penerima berisi minimal satu filter intent, nilai default android:exported adalah "true".

Penerima siaran yang diekspor secara sengaja tanpa kontrol akses yang tepat dapat disalahgunakan jika developer tidak bermaksud agar penerima siaran tersebut dipanggil oleh semua aplikasi.

Dampak

Penerima siaran yang diterapkan dengan tidak aman dapat disalahgunakan oleh penyerang untuk mendapatkan akses yang tidak sah guna menjalankan perilaku dalam aplikasi yang tidak ingin diekspos oleh developer kepada pihak ketiga.

Mitigasi

Menghindari masalah sepenuhnya

Untuk menyelesaikan dilema sepenuhnya, tetapkan exported ke false:

<receiver android:name=".MyReceiver" android:exported="false">
    <intent-filter>
        <action android:name="com.example.myapp.MY_ACTION" />
    </intent-filter>
</receiver>

Menggunakan panggilan dan callback

Jika Anda menggunakan penerima siaran untuk tujuan aplikasi internal (yaitu notifikasi penyelesaian peristiwa), Anda dapat menyusun ulang kode untuk meneruskan callback yang akan diaktifkan setelah penyelesaian peristiwa.

Pemroses penyelesaian peristiwa

Kotlin

interface EventCompletionListener {
    fun onEventComplete(data: String)
}

Java

public interface EventCompletionListener {
    public void onEventComplete(String data);
}
Tugas aman

Kotlin

class SecureTask(private val listener: EventCompletionListener?) {
    fun executeTask() {
        // Do some work...

        // Notify that the event is complete
        listener?.onEventComplete("Some secure data")
    }
}

Java

public class SecureTask {

    final private EventCompletionListener listener;

    public SecureTask(EventCompletionListener listener) {
        this.listener = listener;
    }

    public void executeTask() {
        // Do some work...

        // Notify that the event is complete
        if (listener != null) {
            listener.onEventComplete("Some secure data");
        }
    }
}
Aktivitas utama

Kotlin

class MainActivity : AppCompatActivity(), EventCompletionListener {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        val secureTask = SecureTask(this)
        secureTask.executeTask()
    }

    override fun onEventComplete(data: String) {
        // Handle event completion securely
        // ...
    }
}

Java

public class MainActivity extends AppCompatActivity implements EventCompletionListener {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        SecureTask secureTask = new SecureTask(this);
        secureTask.executeTask();
    }

    @Override
    public void onEventComplete(String data) {
        // Handle event completion securely
        // ...
    }
}

Mengamankan penerima siaran dengan izin

Hanya daftarkan penerima dinamis untuk siaran yang dilindungi (siaran yang hanya dapat dikirim oleh aplikasi tingkat sistem) atau dengan izin tingkat tanda tangan yang dideklarasikan sendiri.

Referensi