Categoria do OWASP: MASVS-STORAGE - Armazenamento (link em inglês)
Visão geral
Este documento aborda vários problemas relacionados à inclusão de arquivos que têm mitigações
semelhantes. Esses problemas se concentram em vulnerabilidades decorrentes do acesso a
arquivos em WebViews e variam de WebSettings
perigosos que permitem o acesso
a arquivos ou a ativação do JavaScript a um método WebKit que cria uma solicitação de seleção
de arquivos. Este documento pode ser útil se você estiver procurando orientações sobre
como corrigir problemas na WebView decorrentes do uso do esquema file://
,
do acesso irrestrito a arquivos locais e do scripting em vários sites.
Mais especificamente, este documento aborda os seguintes tópicos:
WebSettings
é uma classe que contém métodos que gerenciam os estados de configuração das WebViews. Esses métodos podem abrir WebViews para diferentes ataques, que serão descritos mais adiante. Neste documento, vamos analisar os métodos relacionados a como os arquivos podem ser acessados e a configuração que permite a execução do JavaScript:- Os métodos
setAllowFileAccess
,setAllowFileAccessFromFileURLs
esetAllowUniversalAccessFromFileURLs
podem ser usados para conceder acesso a arquivos locais usando um URL do esquema de arquivos (file://
). No entanto, eles podem ser explorados por scripts maliciosos para acessar arquivos locais arbitrários a que o aplicativo tem acesso, como a própria pasta/data/
. Por esse motivo, esses métodos foram sinalizados como não seguros e descontinuados na API 30 em favor de alternativas mais seguras, comoWebViewAssetLoader
. - O método
setJavascriptEnabled
pode ser usado para ativar a execução de JavaScript nas WebViews. Isso deixa os aplicativos vulneráveis a XSS baseado em arquivos. Especialmente quando configurado para permitir o carregamento de arquivos locais ou conteúdo da Web não confiável que pode conter código executável, configurado para permitir o acesso a arquivos que podem ser criados ou alterados por fontes externas ou permitir que WebViews executem JavaScript, os usuários e os dados deles são colocados em risco. WebChromeClient.onShowFileChooser
é um método pertencente ao pacoteandroid.webkit
, que fornece ferramentas de navegação na Web. Esse método pode ser usado para permitir que os usuários selecionem arquivos em uma WebView. No entanto, esse recurso pode ser usado indevidamente porque as WebViews não impõem restrições ao arquivo selecionado.
Impacto
O impacto da inclusão de arquivos pode depender de quais WebSettings são configuradas na
WebView. Permissões de arquivo muito amplas podem permitir que invasores acessem arquivos locais
e roubem dados sensíveis, PII (informações de identificação pessoal) ou dados
privados do app. A ativação da execução do JavaScript pode permitir que invasores executem JavaScript
em uma WebView ou no dispositivo de um usuário. Os arquivos selecionados usando o
método onShowFileChooser
podem comprometer a segurança do usuário, já que não há como
o método ou a WebView garantir que a origem do arquivo seja confiável.
Risco: acesso arriscado a arquivos pelo file://
Ativar setAllowFileAccess
, setAllowFileAccessFromFileURLs
e
setAllowUniversalAccessFromFileURLs
pode permitir que intents maliciosas e solicitações da WebView
com um contexto file://
acessem arquivos locais arbitrários, incluindo
cookies da WebView e dados privados do app. Além disso, o uso do método onShowFileChooser
permite que os usuários selecionem e façam o download de arquivos de fontes não confiáveis.
Esses métodos podem levar à exfiltração de PII, credenciais de login ou outros dados sensíveis, dependendo da configuração do aplicativo.
Mitigações
Validar URLs de arquivos
Se o app exigir acesso a arquivos por URLs file://
, é importante
permitir apenas URLs específicos conhecidos por serem legítimos, evitando
erros comuns.
Usar o WebViewAssetLoader
Use WebViewAssetLoader
em vez dos métodos mencionados. Esse método usa
o esquema http(s)//:
em vez de um esquema file://
para acessar recursos do sistema de arquivos
local e não é vulnerável ao ataque descrito.
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");
Desativar métodos perigosos do WebSettings
Os valores dos métodos setAllowFileAccess()
,
setAllowFileAccessFromFileURLs()
e setAllowUniversalAccessFromFileURLs()
são definidos como TRUE
por padrão no nível 29 da API e anteriores, e FALSE
no nível
30 da API e mais recentes.
Se for necessário configurar outros WebSettings
, é melhor
desativá-los explicitamente, especialmente para apps com nível de API
igual ou inferior a 29.
Risco: XSS baseado em arquivos
A definição do método setJavacriptEnabled
como TRUE
permite que o JavaScript seja
executado em um WebView. Em combinação com o acesso a arquivos ativado, conforme
descrito anteriormente, o XSS baseado em arquivos é possível pela execução de código em
arquivos arbitrários ou sites maliciosos abertos na WebView.
Mitigações
Impedir que os WebViews carreguem arquivos locais
Assim como no risco anterior, o XSS baseado em arquivos pode ser evitado se
setAllowFileAccess()
, setAllowFileAccessFromFileURLs()
e
setAllowUniversalAccessFromFileURLs()
forem definidos como FALSE
.
Impedir que as WebViews executem JavaScript
Defina o método setJavascriptEnabled
como FALSE
para que o JavaScript não possa ser
executado nas WebViews.
Impedir que os WebViews carreguem conteúdo não confiável
Às vezes, é necessário ativar essas configurações nas WebViews. Nesse caso, é importante garantir que apenas conteúdo confiável seja carregado. Limitar a
execução de JavaScript apenas ao que você controla e não permitir JavaScript
arbitrário é uma boa maneira de garantir a confiabilidade do conteúdo. Caso contrário,
impedir o carregamento de tráfego de texto não criptografado garante que as WebViews com
configurações perigosas não consigam carregar URLs HTTP. Isso pode ser feito
no manifesto, definindo android:usesCleartextTraffic
como
False
, ou definindo um Network Security Config
que proíbe o tráfego
HTTP.
Recursos
- Página de referência da API setAllowUniversalAccessFromFileURLs
- Página de referência da API setAllowFileAccessFromFileURLs
- Página de referência da API WebViewAssetLoader
- Documentação do CodeQL
- Blog com segurança excessiva
- Página de referência de onShowFileChooser