WebView – Jembatan native

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).
  • 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