WebViews – небезопасное включение файлов

Категория OWASP: MASVS-STORAGE: Хранилище

Обзор

В этом документе рассматривается несколько проблем, связанных с включением файлов, которые имеют схожие меры по снижению риска. Эти проблемы связаны с уязвимостями, возникающими при доступе к файлам в WebViews, и варьируются от опасных WebSettings разрешающих доступ к файлам или включающих JavaScript, до метода WebKit, который создает запрос на выбор файла. Этот документ будет полезен, если вы ищете рекомендации по устранению проблем в WebView, возникающих из-за использования схемы file:// , неограниченного доступа к локальным файлам и межсайтовых сценариев.

Более конкретно, этот документ охватывает следующие темы:

  • WebSettings — это класс, содержащий методы, которые управляют состояниями настроек для WebViews. Эти методы могут открыть WebViews для различных атак, которые будут описаны позже. В этом документе мы рассмотрим методы, относящиеся к доступу к файлам, и настройку, позволяющую выполнять JavaScript:
  • Методы setAllowFileAccess , setAllowFileAccessFromFileURLs и setAllowUniversalAccessFromFileURLs можно использовать для предоставления доступа к локальным файлам с использованием URL-адреса файловой схемы ( file:// ). Однако они могут быть использованы вредоносными сценариями для доступа к произвольным локальным файлам, к которым у приложения есть доступ, например к их собственной папке /data/ . По этой причине эти методы были помечены как небезопасные и объявлены устаревшими в API 30 в пользу более безопасных альтернатив, таких как WebViewAssetLoader .
  • Метод setJavascriptEnabled можно использовать для включения выполнения JavaScript в WebViews. Это делает приложения уязвимыми для файлового XSS. Пользователи и их данные подвергаются риску, особенно если они настроены на разрешение загрузки локальных файлов или ненадежного веб-контента, который может содержать исполняемый код, настроен на разрешение доступа к файлам, которые могут быть созданы или изменены внешними источниками, или позволяют веб-представлениям выполнять JavaScript. .
  • WebChromeClient.onShowFileChooser — это метод, принадлежащий пакету android.webkit , который предоставляет инструменты просмотра веб-страниц. Этот метод можно использовать, чтобы позволить пользователям выбирать файлы в WebView. Однако этой функцией можно злоупотреблять, поскольку WebViews не налагает ограничений на выбор файла.

Влияние

Влияние включения файла может зависеть от того, какие параметры WebSettings настроены в WebView. Чрезмерно широкие права доступа к файлам могут позволить злоумышленникам получить доступ к локальным файлам и украсть конфиденциальные данные, PII (персональную информацию) или данные частных приложений. Включение выполнения JavaScript может позволить злоумышленникам запускать JavaScript внутри WebView или на устройстве пользователя. Файлы, выбранные с помощью метода onShowFileChooser могут поставить под угрозу безопасность пользователя, поскольку метод или WebView не могут гарантировать, что источник файла является надежным.

Риск: рискованный доступ к файлам через file://

Включение setAllowFileAccess , setAllowFileAccessFromFileURLs и setAllowUniversalAccessFromFileURLs может разрешить злонамеренным намерениям и запросам WebView с контекстом file:// доступ к произвольным локальным файлам, включая файлы cookie WebView и личные данные приложения. Кроме того, использование метода onShowFileChooser может позволить пользователям выбирать и загружать файлы из ненадежных источников.

Все эти методы могут привести к утечке личных данных, учетных данных для входа или других конфиденциальных данных, в зависимости от конфигурации приложения.

Смягчения

Проверка URL-адресов файлов

Если вашему приложению требуется доступ к файлам через URL-адреса file:// , важно внести в белый список только определенные URL-адреса, которые заведомо являются законными, чтобы избежать распространенных ошибок .

Используйте WebViewAssetLoader.

Используйте WebViewAssetLoader вместо упомянутых методов. Этот метод использует схему http(s)//: вместо схемы file:// для доступа к ресурсам локальной файловой системы и не уязвим для описанной атаки.

Котлин

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

Ява

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

Отключить опасные методы WebSettings

Значения методов setAllowFileAccess() , setAllowFileAccessFromFileURLs() и setAllowUniversalAccessFromFileURLs() по умолчанию установлены в TRUE на уровне API 29 и ниже и FALSE на уровне API 30 и выше.

Если есть необходимость настроить другие WebSettings , лучше всего явно отключить эти методы, особенно для приложений, ориентированных на уровни API, меньшие или равные 29.


Риск: файловый XSS

Установка для метода setJavacriptEnabled значения TRUE позволяет выполнять JavaScript внутри WebView, а в сочетании с включенным доступом к файлам, как описано ранее, XSS на основе файлов возможен посредством выполнения кода в произвольных файлах или вредоносных веб-сайтов, открытых в WebView.

Смягчения

Запретить WebViews загружать локальные файлы

Как и в случае с предыдущим риском, файлового XSS можно избежать, если setAllowFileAccess() , setAllowFileAccessFromFileURLs() и setAllowUniversalAccessFromFileURLs() установлено значение FALSE .

Запретить WebViews выполнять JavaScript

Установите для метода setJavascriptEnabled значение FALSE , чтобы JavaScript не мог выполняться в WebViews.

Убедитесь, что WebViews не загружают ненадежный контент

Иногда включение этих настроек необходимо в WebViews. В этом случае важно обеспечить загрузку только доверенного контента. Ограничение выполнения JavaScript только тем, что вы контролируете, и запрет произвольного JavaScript — один из хороших способов обеспечить надежность контента. В противном случае предотвращение загрузки трафика открытого текста гарантирует, что WebViews с опасными настройками, по крайней мере, не смогут загружать URL-адреса HTTP. Это можно сделать либо через манифест, установив android:usesCleartextTraffic значение False , либо установив Network Security Config , которая запрещает HTTP-трафик.


Ресурсы