Kategori OWASP: MASVS-CODE: Kualitas Kode
Ringkasan
Pemuatan URI yang Tidak Aman terjadi saat aplikasi Android gagal mengevaluasi validitas URI dengan benar sebelum memuatnya ke WebView.
Alasan yang mendasari jenis kerentanan ini adalah bahwa URI terdiri dari beberapa bagian, yang setidaknya, skema dan host (dari bagian otoritas) harus terverifikasi (misalnya diizinkan) sebelum URI dimuat ke WebView atau digunakan secara internal oleh aplikasi.
Kesalahan yang paling umum meliputi:
- Memeriksa host, tetapi tidak memeriksa skema sehingga penyerang dapat menggunakan skema seperti
http://
,content://
, ataujavascript://
dengan host yang diautentikasi. - Gagal mengurai URI dengan benar, terutama ketika URI diterima sebagai string.
- Memvalidasi skema, tetapi tidak memvalidasi host (validasi host tidak memadai).
Terkait dengan kasus terakhir, hal ini biasanya terjadi saat aplikasi perlu mengizinkan
subdomain arbitrer dari domain primer. Jadi, meskipun nama host telah
diekstrak dengan benar, aplikasi akan menggunakan metode seperti startsWith
, endsWith,
, atau
contains
dari class java.lang.String
untuk memvalidasi keberadaan domain
primer di bagian string yang diekstrak. Jika tidak digunakan dengan benar, metode ini dapat
menyebabkan hasil yang salah dan memaksa aplikasi untuk memercayai host
yang berpotensi berbahaya.
Dampak
Dampak dapat bervariasi bergantung pada konteks tempat host digunakan. Memuat URI berbahaya (yaitu yang mengabaikan pemfilteran/daftar yang diizinkan) di WebView berpotensi menyebabkan pengambilalihan akun (mis. menggunakan phishing), eksekusi kode (mis., memuat JavaScript berbahaya), atau pembobolan perangkat (mengeksploitasi kode yang dikirimkan menggunakan hyperlink).
Mitigasi
Saat menangani URI string, sebaiknya urai string sebagai URI serta lakukan validasi skema dan host:
Kotlin
fun isUriTrusted(incomingUri: String, trustedHostName: String): Boolean {
try {
val uri = Uri.parse(incomingUri)
return uri.scheme == "https" && uri.host == trustedHostName
} catch (e: NullPointerException) {
throw NullPointerException("incomingUri is null or not well-formed")
}
}
Java
public static boolean isUriTrusted(String incomingUri, String trustedHostName)
throws NullPointerException {
try {
Uri uri = Uri.parse(incomingUri);
return uri.getScheme().equals("https") &&
uri.getHost().equals(trustedHostName);
} catch (NullPointerException e) {
throw new NullPointerException(
"incomingUri is null or not well-formed");
}
}
Untuk validasi host, setelah mengisolasi bagian URI yang sesuai, sebaiknya
lakukan validasi host sepenuhnya (bukan sebagian) guna mengidentifikasi secara akurat apakah
host dipercaya atau tidak. Jika penggunaan metode seperti startsWith
atau endsWith
tidak dapat dihindari, sebaiknya gunakan sintaksis yang benar dan tidak mengabaikan
karakter atau simbol yang diperlukan (misalnya, endsWith
memerlukan karakter titik
".
" sebelum nama domain untuk pencocokan yang akurat). Tidak mencantumkan
karakter ini dapat menyebabkan pencocokan yang tidak akurat dan membahayakan keamanan. Karena
subdomain dapat disusun bertingkat tanpa batasan, pencocokan ekspresi reguler bukanlah
strategi yang direkomendasikan untuk memvalidasi nama host.