WebViews: Inclusión de archivos no seguros

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 vulnerabilidades derivadas del acceso a archivos dentro de WebViews y abarcan desde WebSettings peligrosos que permiten el acceso a archivos o habilitan JavaScript, hasta un método de 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 surjan del uso del esquema file://, el acceso sin restricciones a archivos locales y la ejecución de secuencias de comandos entre sitios.

Más específicamente, 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 relacionados con la forma en que se puede acceder a los archivos y el parámetro de configuración que permite que se ejecute JavaScript:
  • Los métodos setAllowFileAccess, setAllowFileAccessFromFileURLs y setAllowUniversalAccessFromFileURLs se pueden usar para otorgar acceso a archivos locales con una URL de esquema de archivo (file://). Sin embargo, las secuencias de comandos maliciosas pueden aprovecharlos para acceder a archivos locales arbitrarios a los que la aplicación tiene acceso, como su propia carpeta /data/. Por este motivo, estos métodos se marcaron como inseguros y dejaron de estar disponibles en la API 30, y se reemplazaron por alternativas más seguras, como WebViewAssetLoader.
  • 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 basadas en archivos. Especialmente cuando se configura para permitir la carga de archivos locales o contenido web no confiable que puede contener código ejecutable, se configura para permitir el acceso a archivos que pueden crearse o cambiarse por fuentes externas, o se permite que las WebViews ejecuten JavaScript, los usuarios y sus datos corren riesgo.
  • WebChromeClient.onShowFileChooser es un método que pertenece al paquete android.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 abusar de esta función porque los WebView no aplican restricciones sobre qué archivo se selecciona.

Impacto

El impacto de la inclusión de archivos puede depender de qué WebSettings se configuran 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 comprometer la seguridad del usuario, ya que no hay forma de que el método o WebView garanticen que la fuente del archivo sea de confianza.

Riesgo: Acceso riesgoso a archivos a través de file://

Habilitar setAllowFileAccess, setAllowFileAccessFromFileURLs y setAllowUniversalAccessFromFileURLs puede permitir que intents maliciosos y solicitudes de WebView con un contexto de file:// accedan a archivos locales arbitrarios, incluidas las cookies de WebView y los datos privados de la app. Además, usar el 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 cualquier otro dato sensible, 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 incluir en la lista de entidades permitidas solo las URLs específicas que se sabe que son legítimas y evitar errores comunes.

Cómo usar 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 local 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 métodos peligrosos de WebSettings

Los valores de los métodos setAllowFileAccess(), setAllowFileAccessFromFileURLs() y setAllowUniversalAccessFromFileURLs() se establecen de forma predeterminada 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 otros WebSettings, lo mejor sería inhabilitar estos métodos de forma explícita, en especial para las apps que segmentan sus versiones para niveles de API menores o iguales a 29.


Riesgo: XSS basado en archivos

Si se configura el método setJavacriptEnabled como TRUE, se permite que se ejecute JavaScript dentro de un WebView y, en combinación con el acceso a archivos habilitado como se describió anteriormente, es posible realizar 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 del WebView.

Mitigaciones

Evita que las WebViews carguen archivos locales

Al igual que con el riesgo anterior, el XSS basado en archivos se puede evitar si setAllowFileAccess(), setAllowFileAccessFromFileURLs() y setAllowUniversalAccessFromFileURLs() se configuran como FALSE.

Cómo evitar que las WebViews ejecuten JavaScript

Establece el método setJavascriptEnabled en FALSE para que no se pueda ejecutar JavaScript en WebViews.

Asegúrate de que las WebViews no carguen contenido que no sea de confianza

A veces, es necesario habilitar estos parámetros de 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 forma de garantizar que el contenido sea confiable. De lo contrario, impedir que se cargue el tráfico de texto no cifrado garantiza que las WebViews con parámetros de configuración peligrosos al menos no puedan cargar URLs de HTTP. Esto se puede hacer a través del manifiesto, configurando android:usesCleartextTraffic en False o estableciendo un Network Security Config que no permita el tráfico HTTP.


Recursos