Категория OWASP: MASVS-STORAGE: Хранилище
Обзор
В этом документе рассматриваются несколько проблем, связанных с включением файлов, для решения которых требуются схожие меры. Эти проблемы связаны с уязвимостями, возникающими при доступе к файлам внутри WebView, и варьируются от опасных WebSettings , разрешающих доступ к файлам или включающих JavaScript, до метода WebKit, создающего запрос на выбор файла. Этот документ будет полезен, если вы ищете рекомендации по устранению проблем в WebView, возникающих из-за использования схемы file:// , неограниченного доступа к локальным файлам и межсайтового скриптинга.
Более конкретно, данный документ охватывает следующие темы:
-
WebSettings— это класс, содержащий методы, управляющие состоянием настроек WebView. Эти методы могут сделать WebView уязвимыми для различных атак, которые будут описаны позже. В этом документе мы рассмотрим методы, относящиеся к способу доступа к файлам, и настройку, разрешающую выполнение JavaScript: - Методы
setAllowFileAccess,setAllowFileAccessFromFileURLsиsetAllowUniversalAccessFromFileURLsможно использовать для предоставления доступа к локальным файлам с помощью схемы URL (file://). Однако они могут быть использованы вредоносными скриптами для доступа к произвольным локальным файлам, к которым приложение имеет доступ, например, к собственной папке/data/. По этой причине эти методы были помечены как небезопасные и устарели в API 30 в пользу более безопасных альтернатив, таких какWebViewAssetLoader. - Метод
setJavascriptEnabledможно использовать для разрешения выполнения JavaScript внутри WebView. Это делает приложения уязвимыми для XSS-атак на основе файлов. Особенно это касается случаев, когда конфигурация разрешает загрузку локальных файлов или ненадежного веб-контента, который может содержать исполняемый код, разрешает доступ к файлам, которые могут быть созданы или изменены внешними источниками, или позволяет WebView выполнять JavaScript, что подвергает риску пользователей и их данные. - Метод
WebChromeClient.onShowFileChooserпринадлежит пакетуandroid.webkit, который предоставляет инструменты для веб-браузинга. Этот метод можно использовать для того, чтобы позволить пользователям выбирать файлы внутри WebView. Однако эта функция может быть использована не по назначению, поскольку WebView не накладывает ограничений на выбор файла.
Влияние
Влияние включения файлов может зависеть от того, какие параметры WebSettings настроены в WebView. Слишком широкие права доступа к файлам могут позволить злоумышленникам получить доступ к локальным файлам и украсть конфиденциальные данные, персональную информацию или личные данные приложения. Включение выполнения 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")
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");
Отключите опасные методы WebSettings.
Значения методов setAllowFileAccess() , setAllowFileAccessFromFileURLs() и setAllowUniversalAccessFromFileURLs() по умолчанию установлены на TRUE для уровней API 29 и ниже и FALSE для уровней API 30 и выше.
Если необходимо настроить другие WebSettings , лучше всего явно отключить эти методы, особенно для приложений, ориентированных на уровни API меньше или равные 29.
Риск: XSS-атака на основе файлов.
Установка значения TRUE для метода setJavacriptEnabled позволяет выполнять JavaScript внутри WebView, и в сочетании с включенным доступом к файлам, как описано ранее, становится возможной XSS-атака на основе файлов путем выполнения кода в произвольных файлах или открытия вредоносных веб-сайтов внутри WebView.
Меры по смягчению последствий
Предотвратить загрузку локальных файлов в WebView.
Как и в случае с предыдущим риском, файловой XSS-атаки можно избежать, если установить значения setAllowFileAccess() , setAllowFileAccessFromFileURLs() и setAllowUniversalAccessFromFileURLs() в значение FALSE .
Предотвратить выполнение JavaScript в WebView.
Установите для метода setJavascriptEnabled значение FALSE , чтобы исключить выполнение JavaScript внутри WebView.
Убедитесь, что WebViews не загружают ненадежный контент.
Иногда включение этих настроек необходимо в WebView. В этом случае важно убедиться, что загружается только доверенный контент. Ограничение выполнения JavaScript только тем, что вы контролируете, и запрет произвольного JavaScript — один из хороших способов обеспечить достоверность контента. В противном случае, предотвращение загрузки трафика в открытом виде гарантирует, что WebView с опасными настройками, по крайней мере, не смогут загружать HTTP-адреса. Это можно сделать либо через манифест, установив android:usesCleartextTraffic в False , либо путем настройки Network Security Config , которая запрещает HTTP-трафик.
Ресурсы
- Страница справочника API setAllowUniversalAccessFromFileURLs
- Страница справочника API setAllowFileAccessFromFileURLs
- Страница справочника API WebViewAssetLoader
- Документация CodeQL
- Перезащищенный блог
- справочная страница onShowFileChooser