WebViews – niebezpieczne łączenie plików

Kategoria OWASP: MASVS-STORAGE: Storage

Przegląd

W tym dokumencie omówiono kilka problemów związanych z dołączaniem plików, które mają podobne rozwiązania. Problemy te dotyczą luk w zabezpieczeniach wynikających z dostępu do plików w komponentach WebView i obejmują niebezpieczne WebSettings umożliwiające dostęp do plików lub włączanie JavaScriptu, a także metodę WebKit, która tworzy żądanie wyboru pliku. Ten dokument może być przydatny, jeśli szukasz wskazówek dotyczących rozwiązywania problemów w komponencie WebView wynikających z używania schematu file://, nieograniczonego dostępu do plików lokalnych i ataków typu cross-site scripting.

W tym dokumencie omawiamy te tematy:

  • WebSettings to klasa zawierająca metody zarządzania stanami ustawień w przypadku elementów WebView. Te metody mogą otwierać widoki WebView na różne ataki, które zostaną opisane później. W tym dokumencie omówimy metody związane z dostępem do plików oraz ustawienie, które umożliwia wykonywanie kodu JavaScript:
  • Metody setAllowFileAccess, setAllowFileAccessFromFileURLssetAllowUniversalAccessFromFileURLs mogą służyć do przyznawania dostępu do plików lokalnych za pomocą adresu URL schematu pliku (file://). Mogą jednak być wykorzystywane przez złośliwe skrypty do uzyskiwania dostępu do dowolnych plików lokalnych, do których aplikacja ma dostęp, np. do własnego folderu /data/. Z tego powodu te metody zostały oznaczone jako niebezpieczne i wycofane w interfejsie API 30 na rzecz bezpieczniejszych alternatyw, takich jak WebViewAssetLoader.
  • Metoda setJavascriptEnabled umożliwia wykonywanie kodu JavaScript w elementach WebView. Powoduje to, że aplikacje są podatne na ataki typu XSS na poziomie pliku. Szczególnie wtedy, gdy komponenty WebView są skonfigurowane tak, aby zezwalać na ładowanie plików lokalnych lub niezaufanych treści internetowych, które mogą zawierać kod wykonywalny, zezwalać na dostęp do plików, które mogą być tworzone lub zmieniane przez źródła zewnętrzne, lub zezwalać na wykonywanie JavaScriptu, użytkownicy i ich dane są narażeni na ryzyko.
  • WebChromeClient.onShowFileChooser to metoda należąca do pakietu android.webkit, który zawiera narzędzia do przeglądania internetu. Ta metoda może być używana, aby umożliwić użytkownikom wybieranie plików w obiekcie WebView. Ta funkcja może jednak być nadużywana, ponieważ widoki WebView nie wymuszają ograniczeń dotyczących wyboru pliku.

Wpływ

Wpływ dołączania plików może zależeć od tego, które ustawienia WebSettings są skonfigurowane w komponencie WebView. Zbyt szerokie uprawnienia do plików mogą umożliwiać osobom przeprowadzającym atak dostęp do plików lokalnych i kradzież danych wrażliwych, informacji umożliwiających identyfikację lub prywatnych danych aplikacji. Włączenie wykonywania kodu JavaScript może umożliwić atakującym uruchamianie kodu JavaScript w obiekcie WebView lub na urządzeniu użytkownika. Pliki wybrane za pomocą metody onShowFileChooser mogą zagrażać bezpieczeństwu użytkownika, ponieważ nie ma możliwości, aby metoda lub WebView zapewniły, że źródło pliku jest zaufane.

Ryzyko: ryzyko dostępu do plików przez file://

Włączenie setAllowFileAccess, setAllowFileAccessFromFileURLssetAllowUniversalAccessFromFileURLs może umożliwić złośliwym aplikacjom i żądaniom WebView w kontekście file:// dostęp do dowolnych plików lokalnych, w tym plików cookie WebView i danych prywatnych aplikacji. Ponadto korzystanie z metody onShowFileChooser może umożliwiać użytkownikom wybieranie i pobieranie plików z niezaufanych źródeł.

W zależności od konfiguracji aplikacji wszystkie te metody mogą prowadzić do wycieku informacji umożliwiających identyfikację, danych logowania lub innych danych wrażliwych.

Środki ograniczające ryzyko

Weryfikowanie adresów URL plików

Jeśli Twoja aplikacja wymaga dostępu do plików za pomocą file://adresów URL, ważne jest, aby na listę dozwolonych dodawać tylko konkretne adresy URL, które są znane jako legalne, i unikać częstych błędów.

Używanie klasy WebViewAssetLoader

Zamiast wymienionych metod używaj metody WebViewAssetLoader. Ta metoda używa schematu http(s)//: zamiast schematu file://, aby uzyskać dostęp do zasobów lokalnego systemu plików, i nie jest podatna na opisany atak.

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

Wyłączanie niebezpiecznych metod WebSettings

Wartości metod setAllowFileAccess(), setAllowFileAccessFromFileURLs()setAllowUniversalAccessFromFileURLs() są domyślnie ustawione na TRUE na poziomie interfejsu API 29 i niższym oraz na FALSE na poziomie interfejsu API 30 i wyższym.

Jeśli istnieje potrzeba skonfigurowania innych WebSettings, najlepiej wyraźnie wyłączyć te metody, zwłaszcza w przypadku aplikacji kierowanych na interfejsy API na poziomie 29 lub niższym.


Ryzyko: atak typu XSS na poziomie pliku

Ustawienie metody setJavacriptEnabled na TRUE umożliwia wykonywanie kodu JavaScript w komponencie WebView. W połączeniu z wcześniej opisanym dostępem do plików możliwe jest przeprowadzenie ataku XSS opartego na plikach przez wykonanie kodu w dowolnych plikach lub złośliwych witrynach otwartych w komponencie WebView.

Środki ograniczające ryzyko

Uniemożliwianie komponentom WebView ładowania plików lokalnych

Podobnie jak w przypadku poprzedniego zagrożenia, ataku typu XSS na poziomie pliku można uniknąć, jeśli parametry setAllowFileAccess(), setAllowFileAccessFromFileURLs()setAllowUniversalAccessFromFileURLs() są ustawione na FALSE.

Zapobieganie wykonywaniu kodu JavaScript przez komponenty WebView

Ustaw metodę setJavascriptEnabled na FALSE, aby uniemożliwić wykonywanie kodu JavaScript w komponentach WebView.

Upewnij się, że komponenty WebView nie wczytują niezaufanych treści

Czasami w komponentach WebView konieczne jest włączenie tych ustawień. W takim przypadku ważne jest, aby wczytywane były tylko zaufane treści. Ograniczenie wykonywania JavaScriptu tylko do tego, nad którym masz kontrolę, i zablokowanie dowolnego JavaScriptu to dobry sposób na zapewnienie wiarygodności treści. W przeciwnym razie zapobieganie ładowaniu ruchu w postaci tekstu nieszyfrowanego sprawi, że komponenty WebView z niebezpiecznymi ustawieniami nie będą mogły ładować adresów URL HTTP. Można to zrobić w pliku manifestu, ustawiając android:usesCleartextTraffic na False, lub konfigurując Network Security Config, które blokują ruch HTTP.


Zasoby