Kategori OWASP: MASVS-STORAGE: Storage
Ringkasan
Dokumen ini membahas beberapa masalah terkait penyertaan file yang memiliki mitigasi serupa. Masalah ini berpusat 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 berguna jika Anda mencari panduan tentang
perbaikan masalah dalam WebView yang timbul dari penggunaan skema file://
, akses tanpa batasan ke file lokal, dan pembuatan skrip lintas situs.
Secara lebih konkret, dokumen ini mencakup topik berikut:
WebSettings
adalah class yang berisi metode yang mengelola status setelan untuk WebView. Metode ini dapat membuka WebView ke berbagai serangan yang akan diuraikan nanti. Dalam dokumen ini, kita akan melihat metode yang berkaitan dengan cara mengakses file, dan setelan yang memungkinkan JavaScript dieksekusi:- Metode
setAllowFileAccess
,setAllowFileAccessFromFileURLs
, dansetAllowUniversalAccessFromFileURLs
dapat digunakan untuk memberikan akses ke file lokal, menggunakan URL skema file (file://
). Namun, metode ini dapat dieksploitasi oleh skrip berbahaya untuk mengakses file lokal arbitrer yang dapat diakses oleh aplikasi, seperti folder/data/
mereka sendiri. Oleh karena itu, metode ini telah ditandai sebagai tidak aman dan tidak digunakan lagi di API 30 untuk mendukung alternatif yang lebih aman, sepertiWebViewAssetLoader
. - 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 paketandroid.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 Berisiko ke File melalui file://
Mengaktifkan setAllowFileAccess
, setAllowFileAccessFromFileURLs
, dan
setAllowUniversalAccessFromFileURLs
dapat memungkinkan maksud jahat 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
memasukkan hanya URL tertentu yang diketahui sah ke dalam daftar yang diizinkan, 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 level API 29 dan yang lebih rendah, serta FALSE
di level API
30 dan yang lebih tinggi.
Jika ada kebutuhan untuk mengonfigurasi WebSettings
lain, sebaiknya
nonaktifkan secara eksplisit metode ini, terutama untuk aplikasi yang menargetkan level API
kurang dari atau sama dengan 29.
Risiko: XSS Berbasis File
Menyetel metode setJavacriptEnabled
ke TRUE
memungkinkan JavaScript dieksekusi dalam WebView, dan jika dikombinasikan dengan akses file yang diaktifkan seperti yang dijelaskan sebelumnya, XSS berbasis file dapat terjadi 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()
disetel ke FALSE
.
Mencegah WebView menjalankan JavaScript
Tetapkan metode setJavascriptEnabled
ke FALSE
agar 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 pada yang Anda kontrol dan melarang JavaScript arbitrer adalah salah satu cara yang baik untuk memastikan konten dapat dipercaya. Jika tidak,
mencegah traffic teks biasa dimuat memastikan bahwa WebView dengan
setelan berbahaya setidaknya tidak dapat memuat URL HTTP. Hal ini dapat dilakukan
melalui manifes, dengan menyetel android:usesCleartextTraffic
ke
False
, atau dengan menyetel Network Security Config
yang melarang traffic
HTTP.
Referensi
- Halaman referensi API setAllowUniversalAccessFromFileURLs
- Halaman referensi API setAllowFileAccessFromFileURLs
- Halaman referensi WebViewAssetLoader API
- Dokumentasi CodeQL
- Blog yang terlalu diamankan
- Halaman referensi onShowFileChooser