WebView – Penyertaan File Tidak Aman

Kategori OWASP: MASVS-STORAGE: Storage

Ringkasan

Dokumen ini membahas beberapa masalah terkait penyertaan file yang memiliki mitigasi yang serupa. Masalah ini berfokus pada kerentanan yang berasal dari akses ke file dalam WebView dan berkisar dari WebSettings berbahaya yang mengizinkan akses file, atau mengaktifkan JavaScript, hingga metode WebKit yang membuat permintaan pemilihan file. Dokumen ini akan membantu jika Anda mencari panduan tentang perbaikan masalah dalam WebView yang timbul dari penggunaan skema file://, akses yang tidak dibatasi ke file lokal, dan pembuatan skrip lintas situs.

Lebih jelasnya, dokumen ini membahas topik berikut:

  • WebSettings adalah class yang berisi metode yang mengelola status setelan untuk WebView. Metode ini dapat membuka WebView untuk berbagai serangan yang akan diuraikan nanti. Dalam dokumen ini, kita akan melihat metode yang berkaitan dengan cara file dapat diakses, dan setelan yang memungkinkan JavaScript dieksekusi:
  • Metode setAllowFileAccess, setAllowFileAccessFromFileURLs, dan setAllowUniversalAccessFromFileURLs dapat digunakan untuk memberikan akses ke file lokal, menggunakan URL skema file (file://). Namun, metode tersebut dapat dieksploitasi oleh skrip berbahaya untuk mengakses file lokal arbitrer yang diakses aplikasi, seperti folder /data/-nya sendiri. Oleh karena itu, metode ini telah ditandai sebagai tidak aman dan tidak digunakan lagi di API 30 untuk mendukung alternatif yang lebih aman, seperti WebViewAssetLoader.
  • Metode setJavascriptEnabled dapat digunakan untuk mengaktifkan eksekusi JavaScript dalam WebView. Hal ini membuat aplikasi rentan terhadap XSS berbasis file. Terutama jika dikonfigurasi untuk mengizinkan pemuatan file lokal atau konten web yang tidak tepercaya yang mungkin berisi kode yang dapat dieksekusi, dikonfigurasi untuk mengizinkan akses ke file yang dapat dibuat atau diubah oleh sumber eksternal, atau mengizinkan WebView untuk menjalankan JavaScript, pengguna dan data mereka akan berisiko.
  • WebChromeClient.onShowFileChooser adalah metode yang termasuk dalam paket android.webkit, yang menyediakan alat penjelajahan web. Metode ini dapat digunakan untuk mengizinkan pengguna memilih file dalam WebView. Namun, fitur ini dapat disalahgunakan karena WebView tidak menerapkan batasan pada file yang dipilih.

Dampak

Dampak penyertaan file dapat bergantung pada WebSettings yang dikonfigurasi di WebView. Izin file yang terlalu luas dapat memungkinkan penyerang mengakses file lokal dan mencuri data sensitif, PII (Informasi Identitas Pribadi), atau data aplikasi pribadi. Mengaktifkan eksekusi JavaScript dapat memungkinkan penyerang menjalankan JavaScript dalam WebView atau di perangkat pengguna. File yang dipilih menggunakan metode onShowFileChooser dapat membahayakan keamanan pengguna karena tidak ada cara bagi metode atau WebView untuk memastikan bahwa sumber file tepercaya.

Risiko: Akses Berbahaya ke File melalui file://

Mengaktifkan setAllowFileAccess, setAllowFileAccessFromFileURLs, dan setAllowUniversalAccessFromFileURLs dapat mengizinkan intent berbahaya dan permintaan WebView dengan konteks file:// untuk mengakses file lokal arbitrer, termasuk cookie WebView dan data pribadi aplikasi. Selain itu, penggunaan metode onShowFileChooser dapat memungkinkan pengguna memilih dan mendownload file dari sumber yang tidak tepercaya.

Semua metode ini dapat menyebabkan pemindahan PII, kredensial login, atau data sensitif lainnya secara tidak sah, bergantung pada konfigurasi aplikasi.

Mitigasi

Memvalidasi URL file

Jika aplikasi Anda memerlukan akses ke file melalui URL file://, penting untuk hanya mengizinkan URL tertentu yang diketahui sah, sehingga menghindari kesalahan umum.

Menggunakan WebViewAssetLoader

Gunakan WebViewAssetLoader, bukan metode yang disebutkan. Metode ini menggunakan skema http(s)//:, bukan skema file://, untuk mengakses aset sistem file lokal dan tidak rentan terhadap serangan yang dijelaskan.

Kotlin

val assetLoader: WebViewAssetLoader = Builder()
  .addPathHandler("/assets/", AssetsPathHandler(this))
  .build()

webView.setWebViewClient(object : WebViewClientCompat() {
  @RequiresApi(21)
  override fun shouldInterceptRequest(view: WebView?, request: WebResourceRequest): WebResourceResponse {
    return assetLoader.shouldInterceptRequest(request.url)
  }

  @Suppress("deprecation") // for API < 21
  override fun shouldInterceptRequest(view: WebView?, url: String?): WebResourceResponse {
    return assetLoader.shouldInterceptRequest(Uri.parse(url))
  }
})

val webViewSettings: WebSettings = webView.getSettings()
// Setting this off for security. Off by default for SDK versions >= 16.
webViewSettings.allowFileAccessFromFileURLs = false
// Off by default, deprecated for SDK versions >= 30.
webViewSettings.allowUniversalAccessFromFileURLs = false
// Keeping these off is less critical but still a good idea, especially if your app is not
// using file:// or content:// URLs.
webViewSettings.allowFileAccess = false
webViewSettings.allowContentAccess = false

// Assets are hosted under http(s)://appassets.androidplatform.net/assets/... .
// If the application's assets are in the "main/assets" folder this will read the file
// from "main/assets/www/index.html" and load it as if it were hosted on:
// https://appassets.androidplatform.net/assets/www/index.html
webView.loadUrl("https://appassets.androidplatform.net/assets/www/index.html")

Java

final WebViewAssetLoader assetLoader = new WebViewAssetLoader.Builder()
         .addPathHandler("/assets/", new AssetsPathHandler(this))
         .build();

webView.setWebViewClient(new WebViewClientCompat() {
    @Override
    @RequiresApi(21)
    public WebResourceResponse shouldInterceptRequest(WebView view, WebResourceRequest request) {
        return assetLoader.shouldInterceptRequest(request.getUrl());
    }

    @Override
    @SuppressWarnings("deprecation") // for API < 21
    public WebResourceResponse shouldInterceptRequest(WebView view, String url) {
        return assetLoader.shouldInterceptRequest(Uri.parse(url));
    }
});

WebSettings webViewSettings = webView.getSettings();
// Setting this off for security. Off by default for SDK versions >= 16.
webViewSettings.setAllowFileAccessFromFileURLs(false);
// Off by default, deprecated for SDK versions >= 30.
webViewSettings.setAllowUniversalAccessFromFileURLs(false);
// Keeping these off is less critical but still a good idea, especially if your app is not
// using file:// or content:// URLs.
webViewSettings.setAllowFileAccess(false);
webViewSettings.setAllowContentAccess(false);

// Assets are hosted under http(s)://appassets.androidplatform.net/assets/... .
// If the application's assets are in the "main/assets" folder this will read the file
// from "main/assets/www/index.html" and load it as if it were hosted on:
// https://appassets.androidplatform.net/assets/www/index.html
webview.loadUrl("https://appassets.androidplatform.net/assets/www/index.html");

Menonaktifkan metode WebSettings yang berbahaya

Nilai metode setAllowFileAccess(), setAllowFileAccessFromFileURLs(), dan setAllowUniversalAccessFromFileURLs() secara default ditetapkan ke TRUE di API level 29 dan yang lebih rendah, serta FALSE di API level 30 dan yang lebih tinggi.

Jika perlu mengonfigurasi WebSettings lain, sebaiknya nonaktifkan metode ini secara eksplisit, terutama untuk aplikasi yang menargetkan level API kurang dari atau sama dengan 29.


Risiko: XSS Berbasis File

Menetapkan metode setJavacriptEnabled ke TRUE memungkinkan JavaScript dieksekusi dalam WebView, dan jika dikombinasikan dengan akses file yang diaktifkan seperti yang diuraikan sebelumnya, XSS berbasis file dapat dilakukan melalui eksekusi kode dalam file arbitrer, atau situs berbahaya yang dibuka dalam WebView.

Mitigasi

Mencegah WebView memuat file lokal

Seperti risiko sebelumnya, XSS berbasis file dapat dihindari jika setAllowFileAccess(), setAllowFileAccessFromFileURLs(), dan setAllowUniversalAccessFromFileURLs() ditetapkan ke FALSE.

Mencegah WebView menjalankan JavaScript

Tetapkan metode setJavascriptEnabled ke FALSE sehingga JavaScript tidak dapat dieksekusi dalam WebView.

Memastikan WebView tidak memuat konten yang tidak tepercaya

Terkadang, mengaktifkan setelan ini diperlukan dalam WebView. Dalam hal ini, penting untuk memastikan bahwa hanya konten tepercaya yang dimuat. Membatasi eksekusi JavaScript hanya ke yang Anda kontrol dan tidak mengizinkan JavaScript arbitrer adalah salah satu cara yang baik untuk memastikan konten dapat dipercaya. Jika tidak, mencegah traffic cleartext dimuat akan memastikan bahwa WebView dengan setelan berbahaya setidaknya tidak dapat memuat URL HTTP. Hal ini dapat dilakukan melalui manifes, menetapkan android:usesCleartextTraffic ke False, atau dengan menetapkan Network Security Config yang melarang traffic HTTP.


Referensi