WebView'ler - Güvenli Olmayan Dosya Dahil Etme

OWASP kategorisi: MASVS-STORAGE: Depolama

Genel Bakış

Bu belgede, benzer çözümler içeren dosya ekleme ile ilgili çeşitli sorunlar ele alınmaktadır. Bu sorunlar, WebView'lardaki dosyalara erişimden kaynaklanan güvenlik açıklarına odaklanmaktadır ve dosya erişimine izin veren veya JavaScript'i etkinleştiren tehlikeli WebSettings'den dosya seçimi isteği oluşturan bir WebKit yöntemine kadar çeşitlilik gösterir. Bu belge, file:// şemasının kullanımı, yerel dosyalara sınırsız erişim ve siteler arası komut dosyası çalıştırma nedeniyle WebView'da ortaya çıkan sorunların giderilmesi konusunda rehberlik arıyorsanız faydalı olacaktır.

Bu belgede aşağıdaki konular ele alınmaktadır:

  • WebSettings, WebView'ların ayar durumlarını yöneten yöntemleri içeren bir sınıftır. Bu yöntemler, WebView'ları daha sonra açıklanacak farklı saldırılara açık hâle getirebilir. Bu belgede, dosyalara erişim yöntemleri ve JavaScript'in yürütülmesine izin veren ayar ele alınacaktır:
  • setAllowFileAccess, setAllowFileAccessFromFileURLs ve setAllowUniversalAccessFromFileURLs yöntemleri, dosya şeması URL'si (file://) kullanılarak yerel dosyalara erişim izni vermek için kullanılabilir. Ancak bu yöntemler, uygulamanın erişebildiği rastgele yerel dosyalara (ör. kendi /data/ klasörleri) erişmek için kötü amaçlı komut dosyaları tarafından kullanılabilir. Bu nedenle, bu yöntemler güvenli olmadığı için işaretlenmiş ve API 30'da WebViewAssetLoader gibi daha güvenli alternatifler lehine kullanımdan kaldırılmıştır.
  • setJavascriptEnabled yöntemi, WebView'larda JavaScript'in yürütülmesini etkinleştirmek için kullanılabilir. Bu durum, uygulamaları dosya tabanlı XSS'ye karşı savunmasız bırakır. Özellikle yerel dosyaların veya yürütülebilir kod içerebilecek güvenilmeyen web içeriklerinin yüklenmesine izin verecek şekilde yapılandırıldığında, harici kaynaklar tarafından oluşturulabilen veya değiştirilebilen dosyalara erişime izin verecek şekilde yapılandırıldığında ya da WebView'ların JavaScript'i yürütmesine izin verildiğinde kullanıcılar ve verileri risk altına girer.
  • WebChromeClient.onShowFileChooser, web'de gezinme araçları sağlayan android.webkit paketine ait bir yöntemdir. Bu yöntem, kullanıcıların bir WebView'da dosya seçmesine izin vermek için kullanılabilir. Ancak WebView'lar hangi dosyanın seçileceği konusunda kısıtlamalar uygulamadığından bu özellik kötüye kullanılabilir.

Etki

Dosya eklemenin etkisi, WebView'da hangi WebSettings'in yapılandırıldığına bağlı olabilir. Aşırı geniş dosya izinleri, saldırganların yerel dosyalara erişmesine ve hassas verileri, kimliği tanımlayabilecek bilgileri (PII) veya özel uygulama verilerini çalmasına olanak tanıyabilir. JavaScript yürütmenin etkinleştirilmesi, saldırganların bir WebView'da veya kullanıcının cihazında JavaScript çalıştırmasına olanak tanıyabilir. onShowFileChooser yöntemi kullanılarak seçilen dosyalar, dosya kaynağının güvenilir olduğunu yöntem veya WebView'in doğrulayabileceği bir yol olmadığından kullanıcı güvenliğini tehlikeye atabilir.

Risk: file:// aracılığıyla dosyalara riskli erişim

setAllowFileAccess, setAllowFileAccessFromFileURLs ve setAllowUniversalAccessFromFileURLs'nin etkinleştirilmesi, kötü amaçlı girişimlerin ve file:// bağlamına sahip WebView isteklerinin, WebView çerezleri ve uygulamaya özel veriler de dahil olmak üzere rastgele yerel dosyalara erişmesine izin verebilir. Ayrıca, onShowFileChooser yöntemi kullanılarak kullanıcıların güvenilmeyen kaynaklardan dosya seçip indirmesine izin verilebilir.

Bu yöntemlerin tümü, uygulama yapılandırmasına bağlı olarak kimliği tanımlayabilecek bilgilerin, giriş kimlik bilgilerinin veya diğer hassas verilerin sızdırılmasına yol açabilir.

Çözümler

Dosya URL'lerini doğrulama

Uygulamanızın file:// URL'ler aracılığıyla dosyalara erişmesi gerekiyorsa yalnızca meşru olduğu bilinen belirli URL'leri izin verilenler listesine eklemeniz ve yaygın hatalardan kaçınmanız önemlidir.

WebViewAssetLoader'ı kullanma

Belirtilen yöntemler yerine WebViewAssetLoader yöntemini kullanın. Bu yöntem, yerel dosya sistemi öğelerine erişmek için file:// şeması yerine http(s)//: şemasını kullanır ve açıklanan saldırıya karşı savunmasız değildir.

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");

Tehlikeli WebSettings yöntemlerini devre dışı bırakma

setAllowFileAccess() yönteminin değeri, API düzeyi 29 ve daha düşük sürümlerde varsayılan olarak TRUE, API düzeyi 30 ve daha yüksek sürümlerde ise FALSE olarak ayarlanır. setAllowFileAccessFromFileURLs() ve setAllowUniversalAccessFromFileURLs() yöntemleri, API düzeyi 16 ve sonraki sürümlerde varsayılan olarak FALSE olarak ayarlanır. (Bu varsayılanlar, yerel dosyalar için aynı kaynak erişimini kısıtlayarak daha katı güvenlik sağlamak, uygulamaları olası siteler arası komut dosyası çalıştırma (XSS) ve yetkisiz dosya erişimine karşı korumak amacıyla API düzeyi 16'da değiştirildi.)

Diğer WebSettings yapılandırmanız gerekiyorsa özellikle API düzeyi 29'dan düşük veya 29'a eşit olan uygulamalarda bu yöntemleri açıkça devre dışı bırakmanız en iyisidir.


Risk: File-Based XSS

setJavacriptEnabled yönteminin TRUE olarak ayarlanması, JavaScript'in WebView içinde yürütülmesine olanak tanır. Daha önce belirtildiği gibi dosya erişimi etkinleştirildiğinde, rastgele dosyalar içindeki kodun yürütülmesi veya WebView'da açılan kötü amaçlı web siteleri aracılığıyla dosya tabanlı XSS mümkün olur.

Çözümler

WebView'ların yerel dosyaları yüklemesini engelleme

Önceki riskte olduğu gibi, setAllowFileAccess(), setAllowFileAccessFromFileURLs() ve setAllowUniversalAccessFromFileURLs() FALSE olarak ayarlanırsa dosya tabanlı XSS önlenebilir.

WebView'ların JavaScript yürütmesini engelleme

JavaScript'in Web Görünümleri'nde yürütülememesi için yöntemi setJavascriptEnabled olarak FALSE ayarlayın.

WebView'ların güvenilir olmayan içerik yüklemediğinden emin olun

Bazen bu ayarların WebView'larda etkinleştirilmesi gerekir. Bu durumda, yalnızca güvenilir içeriğin yüklendiğinden emin olmak önemlidir. JavaScript'in yalnızca kontrol ettiğiniz kısımlarda çalışmasına izin vermek ve rastgele JavaScript'e izin vermemek, içeriğin güvenilir olmasını sağlamanın iyi bir yoludur. Aksi takdirde, şifresiz metin trafiğinin yüklenmesini önlemek, tehlikeli ayarları olan WebView'ların en azından HTTP URL'lerini yükleyememesini sağlar. Bu, manifest aracılığıyla, android:usesCleartextTraffic ayarını False olarak belirleyerek veya HTTP trafiğine izin vermeyen bir Network Security Config ayarı belirleyerek yapılabilir.


Kaynaklar