Categoría de OWASP: MASVS-PLATFORM: Interacción con la plataforma
Descripción general
Un puente nativo, a veces conocido como puente JavaScript, es un mecanismo que
y facilita la comunicación entre un WebView y código nativo de Android, lo que se logra mediante
con el método addJavascriptInterface
Esto permite la comunicación bidireccional entre el código JavaScript que se ejecuta en WebView y el código Java de la aplicación para Android. El método addJavascriptInterface
expone un objeto Java a todos los fotogramas de una WebView, y cualquier fotograma puede acceder al nombre del objeto y llamar a métodos en él. Sin embargo, no existe un mecanismo
para que la aplicación
verificar el origen del fotograma de llamada dentro de WebView, lo que aumenta la seguridad
inquietudes, ya que la confiabilidad del contenido sigue siendo indeterminada.
También se puede implementar un puente nativo con canales de mensajes HTML usando
WebViewCompat.postWebMessage
o
WebMessagePort.postMessage
para comunicarse con JavaScript
Window.postMessage
WebViewCompat.postWebMessage
y
WebMessagePort.postMessage
puede aceptar mensajes de JavaScript enviados a través de
Window.postMessage
, que se ejecutará dentro de WebView.
Existen varios riesgos asociados con los puentes nativos:
- Puentes basados en JavascriptInterface:
- El método
addJavascriptInterface
inserta un objeto Java suministrado en cada fotograma de WebView, incluidos los iframes, lo que significa que es susceptible de ataque de terceros maliciosos que introduzcan marcos en un sitio web legítimo. Las aplicaciones orientadas al nivel de API 16 o versiones anteriores corren el riesgo de sufrir porque este método puede usarse para permitir que JavaScript controle el host y mantener la integridad de su aplicación. - Refleja el contenido que no es de confianza proporcionado por el usuario en WebViews nativas habilitadas con puente permite ataques de secuencias de comandos entre sitios (XSS).
- El método
- Puentes basados en MessageChannel:
- La falta de verificaciones de origen en los extremos de los canales de mensajes significa que se aceptarán mensajes de cualquier remitente, incluidos aquellos que contengan código malicioso.
- Es posible exponer Java accidentalmente a JavaScript arbitrario.
Impacto
Los métodos addJavascriptInterface
, postWebMessage
y postMessage
pueden ser
que los agentes maliciosos aprovechan para acceder, manipular o inyectar el código que controlan
en un componente WebView. Esto puede provocar que se redireccione a los usuarios a sitios maliciosos,
cargar contenido malicioso o ejecutar un código malicioso en sus dispositivos que
puede extraer datos sensibles o lograr la elevación de privilegios.
Riesgo: Riesgos de addJavascriptInterface
WebView implementa funciones básicas de un navegador, como el procesamiento de páginas,
navegación y ejecución de JavaScript. WebView se puede usar dentro de una aplicación
para mostrar contenido web como parte del diseño de una actividad. La implementación de un puente nativo dentro de un WebView con el método addJavascriptInterface
puede crear problemas de seguridad, como la secuencia de comandos entre sitios (XSS), o permitir que los atacantes carguen contenido no confiable a través de la inyección de interfaz y manipulen la aplicación host de formas no deseadas, ejecutando código Java con los permisos de la aplicación host.
Mitigaciones
Inhabilita JavaScript
En situaciones en las que WebView no requiere JavaScript, no llames a setJavaScriptEnabled
dentro de WebSettings
(por ejemplo, mientras se muestra contenido HTML estático). De forma predeterminada, la ejecución de JavaScript está inhabilitada en WebView.
Quita la interfaz de JavaScript cuando se carga contenido que no es de confianza
Asegúrate de que se quiten los objetos de la interfaz de JavaScript llamando
removeJavascriptInterface
antes de que la
WebView. Por ejemplo, esto puede hacerse en una llamada a
shouldInterceptRequest
Kotlin
webView.removeJavascriptInterface("myObject")
Java
webView.removeJavascriptInterface("myObject");
Carga solo contenido web a través de HTTPS
Si necesitas cargar contenido que no sea de confianza, asegúrate de que WebView cargue contenido web en
una conexión cifrada (consulta también nuestras pautas sobre texto sin cifrar)
Comunicaciones). Evitar que la carga inicial de la página se realice en
conexiones no encriptadas estableciendo android:usesCleartextTraffic
en false
en
el archivo AndroidManifest
o no permitir el tráfico HTTP en una seguridad de red
config. Consulta la documentación de usesCleartextTraffic
para obtener más información.
información.
XML
<application
android:usesCleartextTraffic="false">
<!-- Other application elements -->
</application>
Para garantizar que no se produzcan redireccionamientos y otras navegaciones en la app sin encriptar
busca el esquema HTTP en loadUrl
, o bien
shouldInterceptRequest
:
Kotlin
fun loadSecureUrl(webView: WebView?, url: String?) {
webView?.let { wv -> // Ensure valid WebView and URL
url?.let {
try {
val uri = URI(url)
if (uri.scheme.equals("https", ignoreCase = true)) { // Enforce HTTPS scheme for security
wv.loadUrl(url)
} else {
// Log an error or handle the case where the URL is not secure
System.err.println("Attempted to load a non-HTTPS URL: $url")
}
} catch (e: Exception) {
// Handle exception for improper URL format
System.err.println("Invalid URL syntax: $url")
}
}
}
}
Java
public void loadSecureUrl(WebView webView, String url) {
if (webView != null && url != null) { // Ensure valid WebView and URL
try {
URI uri = new URI(url);
String scheme = uri.getScheme();
if ("https".equalsIgnoreCase(scheme)) { // Enforce HTTPS scheme for security
webView.loadUrl(url);
} else {
// Log an error or handle the case where the URL is not secure
System.err.println("Attempted to load a non-HTTPS URL: " + url);
}
} catch (URISyntaxException e) {
// Handle exception for improper URL format
System.err.println("Invalid URL syntax: " + url);
}
}
}
Valida el contenido que no sea de confianza
Si se cargan vínculos externos en un componente WebView, valida tanto el esquema como el host. (agregar dominios a la lista de entidades permitidas). El navegador predeterminado debe abrir los dominios que no estén en la lista de entidades permitidas.
No cargues contenido no confiable
Si es posible, carga solo el contenido y las URLs con permisos estrictos que pertenezcan al desarrollador de la app en WebView.
No expongas datos sensibles
Si tu aplicación accede a datos sensibles con una WebView, considera usar el método clearCache
para borrar los archivos almacenados de forma local antes de usar la interfaz de JavaScript. También puedes usar encabezados del servidor, como no-store, para
indican que una aplicación no debería almacenar
en caché un contenido determinado.
No expongas funciones sensibles
Si tu aplicación requiere permisos sensibles o recopila datos sensibles, asegúrate de que se llame desde un código dentro de la aplicación y de que a los usuarios. Evita usar interfaces de JavaScript para cualquier operaciones sensibles o datos del usuario.
Orientación al nivel de API 21 o superior
Una forma segura de usar el método addJavascriptInterface
es orientarlo al nivel de API 21 o superior. Para ello, asegúrate de que se llame al método solo cuando se ejecute en el nivel de API 21 o superior. Antes del nivel de API 21, JavaScript podía usar el reflejo para acceder al público
campos de un objeto insertado.
Riesgo: Riesgos de MessageChannel
La falta de control de origen en postWebMessage()
y postMessage()
podría permitir
que los atacantes intercepten mensajes o envíen mensajes a controladores nativos.
Mitigaciones
Cuando configures postWebMessage()
o postMessage()
, evita el uso de * como origen de destino y, en su lugar, especifica de forma explícita el dominio de envío esperado para permitir solo los mensajes de dominios de confianza.
Recursos
- Prácticas recomendadas de postMessage()
- Documentación de addJavascriptInterface
- Documentación de postMessage()
- Documentación de WebMessagePort.postMessage()
- Documentación de WebViewClient.shouldInterceptRequest
- Documentación de los consejos de seguridad relacionados con addJavascriptInterface
- Documentación de clearCache
- Documentación de removeJavascript
- Habilitar JavaScript en WebViews