WebView'ler - Güvenli Olmayan Dosya Dahil Etme

OWASP kategorisi: MASVS-STORAGE: Depolama

Genel Bakış

Bu dokümanda, dosya dahil etmeyle ilgili ve benzer çözümleri paylaşan çeşitli sorunlar ele alınmaktadır. Bu sorunlar, WebView'lardaki dosyalara erişimden kaynaklanan güvenlik açıklarına odaklanı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. file:// şemasının kullanılması, yerel dosyalara sınırsız erişim ve siteler arası komut dosyası çalıştırma nedeniyle WebView'de ortaya çıkan sorunların giderilmesi konusunda yardıma ihtiyacınız varsa bu doküman size yardımcı olacaktır.

Daha ayrıntılı olarak belirtmek gerekirse bu dokümanda aşağıdaki konular ele alınmaktadır:

  • WebSettings, WebView'lerin ayar durumlarını yöneten yöntemler içeren bir sınıftır. Bu yöntemler, WebView'leri daha sonra açıklanacak farklı saldırılara açabilir. Bu dokümanda, dosyalara nasıl erişilebileceğiyle ilgili yöntemlere ve JavaScript'in yürütülmesine izin veren ayarlara bakacağız:
  • 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, kötü amaçlı komut dosyaları tarafından uygulamanın erişebildiği herhangi bir yerel dosyaya (ör. kendi /data/ klasörü) erişmek için kullanılabilir. Bu nedenle, bu yöntemler güvenli değil olarak işaretlendi ve API 30'da WebViewAssetLoader gibi daha güvenli alternatifler lehine kullanımdan kaldırıldı.
  • setJavascriptEnabled yöntemi, JavaScript'in WebView'lerde 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çeriğinin yüklenmesine izin verecek şekilde yapılandırıldığında, harici kaynaklar tarafından oluşturulabilecek veya değiştirilebilecek dosyalara erişime izin verecek şekilde yapılandırıldığında ya da WebView'ların JavaScript'i çalıştırmasına izin verildiğinde kullanıcılar ve verileri riske atılır.
  • WebChromeClient.onShowFileChooser, web tarama araçları sağlayan android.webkit paketine ait bir yöntemdir. Bu yöntem, kullanıcıların bir Web Görünümü'nde dosya seçmesine izin vermek için kullanılabilir. Ancak WebView'ler hangi dosyanın seçileceğiyle ilgili kısıtlamalar uygulamadığından bu özellik kötüye kullanılabilir.

Etki

Dosya eklemenin etkisi, WebView'de hangi WebSettings ayarlarının 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 gizli uygulama verilerini çalmasına neden olabilir. JavaScript yürütme özelliğini etkinleştirmek, saldırganların bir WebView içinde veya kullanıcının cihazında JavaScript çalıştırmasına izin verebilir. onShowFileChooser yöntemi kullanılarak seçilen dosyalar, yöntemin veya Web Görünümü'nün dosya kaynağının güvenilir olduğundan emin olmasının bir yolu olmadığından kullanıcı güvenliğini tehlikeye atabilir.

Risk: file:// üzerinden dosyalara riskli erişim

setAllowFileAccess, setAllowFileAccessFromFileURLs ve setAllowUniversalAccessFromFileURLs'yi etkinleştirmek, file:// bağlamına sahip kötü amaçlı intent'lerin ve WebView isteklerinin WebView çerezleri ve uygulama gizli verileri dahil olmak üzere rastgele yerel dosyalara erişmesine izin verebilir. Ayrıca, onShowFileChooser yönteminin kullanılması kullanıcıların güvenilmeyen kaynaklardan dosya seçip indirmesine izin verebilir.

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 neden olabilir.

Çözümler

Dosya URL'lerini doğrulama

Uygulamanız file:// URL'leri üzerinden dosyalara erişim gerektiriyorsa yaygın hatalardan kaçınmak için yalnızca meşru olduğu bilinen belirli URL'leri izin verilenler listesine eklemeniz önemlidir.

WebViewAssetLoader'ı kullanma

Söz konusu 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(), setAllowFileAccessFromFileURLs() ve setAllowUniversalAccessFromFileURLs() yöntemlerinin değerleri, API düzeyi 29 ve önceki sürümlerde varsayılan olarak TRUE, API düzeyi 30 ve sonraki sürümlerde ise FALSE olarak ayarlanır.

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


Risk: Dosya Tabanlı XSS

setJavacriptEnabled yönteminin TRUE olarak ayarlanması, JavaScript'in bir WebView'de yürütülmesine olanak tanır. Ayrıca, daha önce belirtildiği gibi dosya erişiminin etkinleştirilmesiyle birlikte, rastgele dosyalarda veya WebView'de açılan kötü amaçlı web sitelerinde kod yürütülerek dosya tabanlı XSS mümkündür.

Çö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'den kaçınılabilir.

WebView'lerin JavaScript yürütmesini engelleme

JavaScript'in WebView'lerde çalıştırılmaması için setJavascriptEnabled yöntemini FALSE olarak ayarlayın.

Web Görünümleri'nin güvenilir olmayan içerik yüklemediğinden emin olun

Bazen WebView'larda bu ayarların etkinleştirilmesi gerekir. Bu durumda, yalnızca güvenilir içeriğin yüklenmesini sağlamak önemlidir. JavaScript'in yürütülmesini yalnızca sizin kontrol ettiğinizlerle sınırlandırmak ve rastgele JavaScript'e izin vermemek, içeriğin güvenilir olmasını sağlamanın iyi bir yoludur. Aksi takdirde, açık metin trafiğinin yüklenmesi engellenerek tehlikeli ayarları olan WebView'ların en azından HTTP URL'lerini yüklemesi önlenebilir. Bu işlem, manifest aracılığıyla android:usesCleartextTraffic değerini False olarak ayarlayarak veya HTTP trafiğine izin vermeyen bir Network Security Config ayarlayarak yapılabilir.


Kaynaklar