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
, dansetAllowUniversalAccessFromFileURLs
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, 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 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
- Halaman referensi API setAllowUniversalAccessFromFileURLs
- Halaman referensi setAllowFileAccessFromFileURLs API
- Halaman referensi WebViewAssetLoader API
- Dokumentasi CodeQL
- Blog yang terlalu aman
- Halaman referensi onShowFileChooser