Kategori OWASP: MASVS-PLATFORM: Interaksi Platform
Ringkasan
Jembatan bawaan, kadang-kadang dikenal
sebagai jembatan JavaScript, adalah mekanisme yang
memfasilitasi komunikasi antara WebView dan kode native Android, yang dicapai dengan
menggunakan metode addJavascriptInterface
. Hal ini memungkinkan komunikasi
dua arah antara kode JavaScript yang berjalan di WebView dan kode Java
aplikasi Android. Metode addJavascriptInterface
mengekspos Java
ke semua frame WebView, dan setiap frame dapat mengakses nama objek
dan memanggil metode di dalamnya. Namun, tidak ada mekanisme bagi aplikasi untuk
memverifikasi asal frame panggilan dalam WebView, yang menimbulkan masalah
keamanan karena kepercayaan konten tetap tidak dapat ditentukan.
Jembatan bawaan juga dapat diimplementasikan dengan saluran pesan HTML menggunakan
WebViewCompat.postWebMessage
Android atau
WebMessagePort.postMessage
untuk berkomunikasi dengan JavaScript
Window.postMessage
. WebViewCompat.postWebMessage
dan
WebMessagePort.postMessage
dapat menerima pesan JavaScript yang dikirim melalui
Window.postMessage
yang akan dieksekusi dalam WebView.
Ada beberapa risiko yang terkait dengan jembatan native:
- Bridge berbasis JavascriptInterface:
- Metode
addJavascriptInterface
memasukkan objek Java yang disediakan ke dalam setiap frame WebView, termasuk iframe, yang berarti metode ini rentan terhadap serangan oleh pihak ketiga berbahaya yang memasukkan frame ke situs yang sah. Aplikasi yang menargetkan API level 16 atau yang lebih lama sangat berisiko diserang karena metode ini dapat digunakan untuk mengizinkan JavaScript mengontrol aplikasi host. - Mencerminkan konten yang disediakan pengguna yang tidak tepercaya di WebView yang mengaktifkan bridge native memungkinkan serangan pembuatan skrip lintas situs (XSS).
- Metode
- Jembatan berbasis MessageChannel:
- Kurangnya pemeriksaan origin pada endpoint saluran pesan berarti pesan akan diterima dari pengirim mana pun, termasuk yang berisi kode berbahaya.
- Anda dapat secara tidak sengaja mengekspos Java ke JavaScript arbitrer.
Dampak
Metode addJavascriptInterface
, postWebMessage
, dan postMessage
dapat
dimanfaatkan oleh pelaku kejahatan untuk mengakses, memanipulasi, atau menyuntikkan kode yang mereka kontrol
menjadi WebView. Hal ini dapat menyebabkan pengguna dialihkan ke situs berbahaya,
memuat konten berbahaya, atau menjalankan kode berbahaya di perangkat mereka yang
dapat mengekstrak data sensitif atau mendapatkan eskalasi hak istimewa.
Risiko: risiko addJavascriptInterface
WebView menerapkan fungsi dasar browser, seperti rendering halaman,
navigasi, dan eksekusi JavaScript. WebView dapat digunakan di dalam aplikasi
untuk menampilkan konten web sebagai bagian dari tata letak aktivitas. Mengimplementasikan bridge native dalam WebView menggunakan metode addJavascriptInterface
dapat menimbulkan masalah keamanan seperti cross-site scripting (XSS), atau memungkinkan penyerang memuat konten tidak tepercaya melalui injeksi antarmuka dan memanipulasi aplikasi host dengan cara yang tidak diinginkan, mengeksekusi kode Java dengan izin aplikasi host.
Mitigasi
Nonaktifkan JavaScript
Dalam skenario ketika WebView tidak memerlukan JavaScript, jangan panggil
setJavaScriptEnabled
dalam WebSettings
(misalnya, meskipun
menampilkan konten HTML statis). Secara {i>default<i}, eksekusi
JavaScript dinonaktifkan di
WebView.
Menghapus antarmuka JavaScript saat memuat konten tidak tepercaya
Pastikan objek dari antarmuka JavaScript dihapus dengan memanggil
removeJavascriptInterface
sebelum konten tidak tepercaya dimuat oleh
WebView. Misalnya, hal ini dapat dilakukan dalam panggilan ke
shouldInterceptRequest
Kotlin
webView.removeJavascriptInterface("myObject")
Java
webView.removeJavascriptInterface("myObject");
Hanya memuat konten web melalui HTTPS
Jika Anda perlu memuat konten tidak tepercaya, pastikan WebView memuat konten web melalui
koneksi yang dienkripsi (lihat juga pedoman kami tentang Cleartext
Komunikasi). Mencegah pemuatan halaman awal dilakukan pada
koneksi yang tidak terenkripsi dengan menyetel android:usesCleartextTraffic
ke false
file AndroidManifest
atau larang traffic HTTP dalam keamanan jaringan
konfigurasi. Lihat dokumentasi usesCleartextTraffic
untuk mengetahui informasi selengkapnya.
Xml
<application
android:usesCleartextTraffic="false">
<!-- Other application elements -->
</application>
Untuk memastikan bahwa pengalihan dan penjelajahan aplikasi lebih lanjut tidak terjadi pada traffic
yang tidak dienkripsi, periksa skema HTTP di loadUrl
atau
shouldInterceptRequest
:
Kotlin
fun loadSecureUrl(webView: WebView?, url: String?) {
webView?.let { wv -> // Ensure valid WebView and URL
url?.let {
try {
val uri = URI(url)
if (uri.scheme.equals("https", ignoreCase = true)) { // Enforce HTTPS scheme for security
wv.loadUrl(url)
} else {
// Log an error or handle the case where the URL is not secure
System.err.println("Attempted to load a non-HTTPS URL: $url")
}
} catch (e: Exception) {
// Handle exception for improper URL format
System.err.println("Invalid URL syntax: $url")
}
}
}
}
Java
public void loadSecureUrl(WebView webView, String url) {
if (webView != null && url != null) { // Ensure valid WebView and URL
try {
URI uri = new URI(url);
String scheme = uri.getScheme();
if ("https".equalsIgnoreCase(scheme)) { // Enforce HTTPS scheme for security
webView.loadUrl(url);
} else {
// Log an error or handle the case where the URL is not secure
System.err.println("Attempted to load a non-HTTPS URL: " + url);
}
} catch (URISyntaxException e) {
// Handle exception for improper URL format
System.err.println("Invalid URL syntax: " + url);
}
}
}
Memvalidasi konten yang tidak tepercaya
Jika ada link eksternal yang dimuat di WebView, validasi skema dan host (domain daftar yang diizinkan). Domain apa pun yang tidak ada dalam daftar yang diizinkan harus dibuka oleh browser default.
Jangan muat konten tidak tepercaya
Jika memungkinkan, hanya muat URL yang dicakup dengan ketat dan konten yang dimiliki oleh developer aplikasi ke dalam WebView.
Jangan ekspos data sensitif
Jika aplikasi Anda mengakses data sensitif dengan WebView, pertimbangkan untuk menggunakan
Metode clearCache
untuk menghapus file yang disimpan secara lokal, sebelum menggunakan
Antarmuka JavaScript. Anda juga dapat menggunakan header sisi server, seperti no-store, untuk
menunjukkan bahwa aplikasi tidak boleh menyimpan konten tertentu ke dalam cache.
Jangan ekspos fungsi yang sensitif
Jika aplikasi Anda memerlukan izin sensitif atau mengumpulkan data sensitif, memastikan bahwa itu dipanggil dari kode dalam aplikasi dan yang pengungkapan informasi diberikan kepada pengguna. Hindari penggunaan antarmuka JavaScript untuk operasi sensitif atau data pengguna.
Menargetkan API level 21 atau yang lebih tinggi
Satu cara aman untuk menggunakan metode addJavascriptInterface
adalah dengan menargetkan level API
21 atau lebih tinggi dengan memastikan metode hanya dipanggil saat berjalan di level API 21
atau yang lebih tinggi. Sebelum API 21, JavaScript dapat menggunakan refleksi untuk mengakses kolom publik
objek yang dimasukkan.
Risiko: Risiko MessageChannel
Kurangnya kontrol origin di postWebMessage()
dan postMessage()
dapat memungkinkan
penyerang mencegat pesan atau mengirim pesan ke pengendali native.
Mitigasi
Saat menyiapkan postWebMessage()
atau postMessage()
, hanya izinkan pesan dari domain tepercaya dengan menghindari penggunaan * sebagai asal target, dan sebagai gantinya tentukan domain pengiriman yang diharapkan secara eksplisit.
Referensi
- Praktik terbaik postMessage()
- Dokumentasi addJavascriptInterface
- Dokumentasi postMessage()
- Dokumentasi WebMessagePort.postMessage()
- Dokumentasi WebViewClient.shouldInterceptRequest
- Dokumentasi saran keamanan terkait addJavascriptInterface
- Dokumentasi clearCache
- Dokumentasi removeJavascript
- mengaktifkan JavaScript di WebView