Категория 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. Слишком широкие права доступа к файлам могут позволить злоумышленникам получить доступ к локальным файлам и украсть конфиденциальные данные, персональные данные (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.
Смягчение последствий
Запретить WebView загружать локальные файлы
Как и в случае с предыдущим риском, XSS на основе файлов можно избежать, если setAllowFileAccess()
, setAllowFileAccessFromFileURLs()
и setAllowUniversalAccessFromFileURLs()
установить в FALSE
.
Запретить WebViews выполнять JavaScript
Установите метод setJavascriptEnabled
в FALSE
, чтобы JavaScript не мог выполняться в WebViews.
Убедитесь, что WebViews не загружают ненадежный контент
Иногда эти настройки необходимо включить в WebView. В этом случае важно обеспечить загрузку только доверенного контента. Ограничение выполнения JavaScript только теми кодами, которые вы контролируете, и запрет произвольного JavaScript — один из хороших способов обеспечить надёжность контента. В противном случае, запрет загрузки открытого текстового трафика гарантирует, что WebView с опасными настройками, как минимум, не смогут загружать HTTP-адреса. Это можно сделать либо через манифест, установив параметр android:usesCleartextTraffic
в False
, либо настроив Network Security Config
, запрещающую HTTP-трафик.
Ресурсы
- Справочная страница API setAllowUniversalAccessFromFileURLs
- Справочная страница API setAllowFileAccessFromFileURLs
- Справочная страница API WebViewAssetLoader
- Документация CodeQL
- Сверхзащищенный блог
- справочная страница onShowFileChooser