Categoría de OWASP: MASVS-STORAGE: Almacenamiento
Descripción general
En este documento, se abordan varios problemas relacionados con la inclusión de archivos que comparten mitigaciones similares. Estos problemas se centran en las vulnerabilidades que surgen del acceso a archivos dentro de WebViews y van desde un WebSettings
peligroso que permite el acceso a archivos o habilita JavaScript hasta un método WebKit que crea una solicitud de selección de archivos. Este documento debería ser útil si buscas orientación para solucionar problemas en WebView que surgen por el uso del esquema file://
, el acceso sin restricciones a archivos locales y la ejecución de secuencias de comandos entre sitios.
Más concretamente, en este documento, se abordan los siguientes temas:
WebSettings
es una clase que contiene métodos que administran los estados de configuración de WebViews. Estos métodos pueden abrir WebViews a diferentes ataques, que se describirán más adelante. En este documento, analizaremos los métodos que se relacionan con la forma en que se puede acceder a los archivos y la configuración que permite que se ejecute JavaScript:- Los métodos
setAllowFileAccess
,setAllowFileAccessFromFileURLs
ysetAllowUniversalAccessFromFileURLs
se pueden usar para otorgar acceso a archivos locales mediante una URL de esquema de archivo (file://
). Sin embargo, las secuencias de comandos maliciosas pueden aprovecharlas para acceder a archivos locales arbitrarios a los que tiene acceso la aplicación, como su propia carpeta/data/
. Por este motivo, estos métodos se marcaron como no seguros y dejaron de estar disponibles en el nivel de API 30 en favor de alternativas más seguras, comoWebViewAssetLoader
. - El método
setJavascriptEnabled
se puede usar para habilitar la ejecución de JavaScript dentro de WebViews. Esto deja a las aplicaciones vulnerables a XSS basado en archivos. Esto es especialmente cierto cuando se configuran para permitir la carga de archivos locales o contenido web no confiable que puede contener código ejecutable, para permitir el acceso a archivos que pueden crear o cambiar fuentes externas, o para permitir que WebViews ejecute JavaScript. En estos casos, los usuarios y sus datos están en riesgo. WebChromeClient.onShowFileChooser
es un método que pertenece al paqueteandroid.webkit
, que proporciona herramientas de navegación web. Este método se puede usar para permitir que los usuarios seleccionen archivos dentro de un WebView. Sin embargo, se puede hacer un uso inadecuado de esta función porque WebViews no aplican restricciones sobre el archivo que se selecciona.
Impacto
El impacto de la inclusión de archivos puede depender de los WebSettings que se configuren en WebView. Los permisos de archivos demasiado amplios pueden permitir que los atacantes accedan a archivos locales y roben datos sensibles, PII (información de identificación personal) o datos privados de la app. Habilitar la ejecución de JavaScript puede permitir que los atacantes ejecuten JavaScript dentro de una WebView o en el dispositivo de un usuario. Los archivos seleccionados con el método onShowFileChooser
podrían poner en riesgo la seguridad del usuario, ya que no hay forma de que el método o WebView se aseguren de que la fuente del archivo sea de confianza.
Riesgo: Acceso riesgoso a archivos a través de file://
Si habilitas setAllowFileAccess
, setAllowFileAccessFromFileURLs
y setAllowUniversalAccessFromFileURLs
, puedes permitir que intents maliciosos y solicitudes de WebView con un contexto file://
accedan a archivos locales arbitrarios, incluidas las cookies de WebView y los datos privados de la app. Además, el uso del método onShowFileChooser
puede permitir que los usuarios seleccionen y descarguen archivos de fuentes no confiables.
Todos estos métodos pueden llevar a la exfiltración de PII, credenciales de acceso o otros datos sensibles, según la configuración de la aplicación.
Mitigaciones
Valida las URLs de los archivos
Si tu app requiere acceso a archivos a través de URLs de file://
, es importante que solo incluyas en la lista de entidades permitidas URLs específicas que se sepa que son legítimas, lo que evitará errores comunes.
Usa WebViewAssetLoader
Usa WebViewAssetLoader
en lugar de los métodos mencionados. Este método usa el esquema http(s)//:
en lugar de un esquema file://
para acceder a los recursos del sistema de archivos locales y no es vulnerable al 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");
Inhabilita los métodos peligrosos de WebSettings
De forma predeterminada, los valores de los métodos setAllowFileAccess()
, setAllowFileAccessFromFileURLs()
y setAllowUniversalAccessFromFileURLs()
se establecen en TRUE
en el nivel de API 29 y versiones anteriores, y en FALSE
en el nivel de API 30 y versiones posteriores.
Si es necesario configurar otro WebSettings
, lo mejor es inhabilitar estos métodos de forma explícita, en especial para las apps orientadas a niveles de API inferiores o iguales a 29.
Riesgo: XSS basado en archivos
Si estableces el método setJavacriptEnabled
en TRUE
, se permite que JavaScript se ejecute dentro de un WebView y, en combinación con el acceso a archivos habilitado como se describió anteriormente, es posible realizar un XSS basado en archivos a través de la ejecución de código dentro de archivos arbitrarios o sitios web maliciosos que se abren dentro de WebView.
Mitigaciones
Evita que WebView cargue archivos locales
Al igual que con el riesgo anterior, se puede evitar el XSS basado en archivos si
setAllowFileAccess()
, setAllowFileAccessFromFileURLs()
y
setAllowUniversalAccessFromFileURLs()
se configuran en FALSE
.
Evita que WebViews ejecute JavaScript
Establece el método setJavascriptEnabled
en FALSE
para que JavaScript no se pueda ejecutar en WebViews.
Asegúrate de que las WebViews no carguen contenido que no sea de confianza
A veces, es necesario habilitar esta configuración en WebViews. En este caso, es importante asegurarse de que solo se cargue contenido de confianza. Limitar la ejecución de JavaScript solo a lo que controlas y no permitir JavaScript arbitrario es una buena manera de garantizar que el contenido sea confiable. De lo contrario, evitar que se cargue el tráfico de texto simple garantiza que los WebViews con parámetros de configuración peligrosos, al menos, no puedan cargar URLs HTTP. Esto se puede hacer a través del manifiesto, configurando android:usesCleartextTraffic
como False
o configurando un Network Security Config
que no permita el tráfico HTTP.
Recursos
- Página de referencia de la API de setAllowUniversalAccessFromFileURLs
- Página de referencia de la API de setAllowFileAccessFromFileURLs
- Página de referencia de la API de WebViewAssetLoader
- Documentación de CodeQL
- Blog con seguridad excesiva
- Página de referencia de onShowFileChooser