Kategori OWASP: MASVS-NETWORK: Komunikasi Jaringan
Ringkasan
DownloadManager adalah layanan sistem yang diperkenalkan di API level 9. Library ini menangani download HTTP yang berjalan lama dan memungkinkan aplikasi mendownload file sebagai tugas latar belakang. API-nya menangani interaksi HTTP dan mencoba ulang download setelah terjadi kegagalan atau setelah terjadi perubahan konektivitas dan dimulai ulang sistem.
DownloadManager memiliki kelemahan yang relevan terkait keamanan yang menjadikannya pilihan yang tidak aman untuk mengelola download di aplikasi Android.
(1) CVE di Penyedia Download
Pada tahun 2018, tiga CVE ditemukan dan ditambal di Download Provider. Berikut ringkasan masing-masing (lihat detail teknis).
- Pembobolan Izin Penyedia Download – Tanpa izin yang diberikan, aplikasi berbahaya dapat mengambil semua entri dari Penyedia Download, yang dapat menyertakan informasi yang berpotensi sensitif seperti nama file, deskripsi, judul, jalur, URL, serta izin BACA/TULIS penuh ke semua file yang didownload. Aplikasi berbahaya dapat berjalan di latar belakang, memantau semua download dan membocorkan kontennya dari jarak jauh, atau memodifikasi file dengan cepat sebelum diakses oleh pemohon yang sah. Hal ini dapat menyebabkan denial-of-service bagi pengguna untuk aplikasi inti, termasuk ketidakmampuan untuk mendownload update.
- Injeksi SQL Penyedia Download – Melalui kerentanan injeksi SQL, aplikasi berbahaya tanpa izin dapat mengambil semua entri dari
Penyedia Download. Selain itu, aplikasi dengan izin terbatas, seperti
android.permission.INTERNET
, juga dapat mengakses semua konten database dari URI yang berbeda. Informasi yang berpotensi sensitif seperti nama file, deskripsi, judul, jalur, URL dapat diambil, dan, bergantung pada izin, akses ke konten yang didownload juga dapat dilakukan. - Pengungkapan Informasi Header Permintaan Penyedia Download – Aplikasi malicious
dengan izin
android.permission.INTERNET
yang diberikan dapat mengambil semua entri dari tabel header permintaan Penyedia Download. Header ini dapat mencakup informasi sensitif, seperti cookie sesi atau header autentikasi, untuk setiap download yang dimulai dari Browser Android atau Google Chrome, di antara aplikasi lainnya. Hal ini memungkinkan penyerang meniru identitas pengguna di platform apa pun tempat data pengguna sensitif diperoleh.
(2) Izin Berbahaya
DownloadManager di level API yang lebih rendah dari 29 memerlukan izin berbahaya –
android.permission.WRITE_EXTERNAL_STORAGE
. Untuk level API 29
dan yang lebih tinggi, izin android.permission.WRITE_EXTERNAL_STORAGE
tidak diperlukan, tetapi URI harus merujuk pada jalur dalam
direktori yang dimiliki oleh aplikasi atau jalur dalam direktori "Download"
level atas.
(3) Ketergantungan pada Uri.parse()
DownloadManager mengandalkan metode Uri.parse()
untuk mengurai lokasi
download yang diminta. Demi performa, class Uri
menerapkan
sedikit atau tidak ada validasi pada input yang tidak tepercaya.
Dampak
Menggunakan DownloadManager dapat menyebabkan kerentanan melalui eksploitasi izin WRITE ke penyimpanan eksternal. Karena izin android.permission.WRITE_EXTERNAL_STORAGE memungkinkan akses luas ke penyimpanan eksternal, penyerang dapat mengubah file dan download secara diam-diam, menginstal aplikasi yang berpotensi membahayakan, menolak layanan ke aplikasi inti, atau menyebabkan aplikasi error. Pelaku berbahaya juga dapat memanipulasi apa yang dikirim ke Uri.parse() untuk menyebabkan pengguna mendownload file berbahaya.
Mitigasi
Daripada menggunakan DownloadManager, siapkan download langsung di aplikasi Anda menggunakan klien HTTP (seperti Cronet), penjadwal/pengelola proses, dan cara untuk memastikan percobaan ulang jika ada kehilangan jaringan. Dokumentasi library menyertakan link ke aplikasi contoh serta petunjuk tentang cara menerapkan library tersebut.
Jika aplikasi Anda memerlukan kemampuan untuk mengelola penjadwalan proses, menjalankan
download di latar belakang, atau mencoba lagi membuat download setelah kehilangan
jaringan, sebaiknya sertakan WorkManager
dan
ForegroundServices
.
Contoh kode untuk menyiapkan download menggunakan Cronet adalah sebagai berikut, yang diambil dari codelab Cronet.
Kotlin
override suspend fun downloadImage(url: String): ImageDownloaderResult {
val startNanoTime = System.nanoTime()
return suspendCoroutine {
cont ->
val request = engine.newUrlRequestBuilder(url, object: ReadToMemoryCronetCallback() {
override fun onSucceeded(
request: UrlRequest,
info: UrlResponseInfo,
bodyBytes: ByteArray) {
cont.resume(ImageDownloaderResult(
successful = true,
blob = bodyBytes,
latency = Duration.ofNanos(System.nanoTime() - startNanoTime),
wasCached = info.wasCached(),
downloaderRef = this@CronetImageDownloader))
}
override fun onFailed(
request: UrlRequest,
info: UrlResponseInfo,
error: CronetException
) {
Log.w(LOGGER_TAG, "Cronet download failed!", error)
cont.resume(ImageDownloaderResult(
successful = false,
blob = ByteArray(0),
latency = Duration.ZERO,
wasCached = info.wasCached(),
downloaderRef = this@CronetImageDownloader))
}
}, executor)
request.build().start()
}
}
Java
@Override
public CompletableFuture<ImageDownloaderResult> downloadImage(String url) {
long startNanoTime = System.nanoTime();
return CompletableFuture.supplyAsync(() -> {
UrlRequest.Builder requestBuilder = engine.newUrlRequestBuilder(url, new ReadToMemoryCronetCallback() {
@Override
public void onSucceeded(UrlRequest request, UrlResponseInfo info, byte[] bodyBytes) {
return ImageDownloaderResult.builder()
.successful(true)
.blob(bodyBytes)
.latency(Duration.ofNanos(System.nanoTime() - startNanoTime))
.wasCached(info.wasCached())
.downloaderRef(CronetImageDownloader.this)
.build();
}
@Override
public void onFailed(UrlRequest request, UrlResponseInfo info, CronetException error) {
Log.w(LOGGER_TAG, "Cronet download failed!", error);
return ImageDownloaderResult.builder()
.successful(false)
.blob(new byte[0])
.latency(Duration.ZERO)
.wasCached(info.wasCached())
.downloaderRef(CronetImageDownloader.this)
.build();
}
}, executor);
UrlRequest urlRequest = requestBuilder.build();
urlRequest.start();
return urlRequest.getResult();
});
}
Referensi
- Halaman dokumentasi utama untuk DownloadManager
- Laporan untuk CVE DownloadManager
- Pembobolan Izin Android CVE 2018-9468
- Injeksi SQL Penyedia Android CVE-2018- 9493
- Penyeberangan Izin Penyedia Download Android CVE2018-9468
- Halaman dokumentasi utama untuk Cronet
- Petunjuk untuk menggunakan Cronet dalam aplikasi
- Contoh penerapan Cronet
- Dokumentasi untuk Uri
- Dokumentasi untuk ForegroundService
- Dokumentasi untuk WorkManager