FlawOpen

flawopen.com/Seguridad de Android WebView/addJavascriptInterface

Android addJavascriptInterface: riesgos y uso seguro

Página de referencia
Respuesta breve

Considera un WebView con addJavascriptInterface como un límite privilegiado. Android inyecta el objeto en todos los frames y la app no puede saber qué frame lo invocó. Si JavaScript controlado por un atacante llega a cualquier frame, puede llamar a los métodos expuestos con los permisos de la app. Reserva los WebView con puente para contenido controlado por la app y carga páginas no confiables en otro WebView sin el puente.

Cómo cambia el puente el impacto de XSS

Un puente ofrece al JavaScript puntos de entrada invocables en la app anfitriona. Android expone el objeto a todos los frames, incluidos los iframes, y addJavascriptInterface no verifica el origen del frame que llama. Un script inyectado puede alcanzar los métodos anotados; sus capacidades dependen de esos métodos y de las comprobaciones de autorización de la app. En las apps cuyo API de destino es 16 o anterior, Android documenta un comportamiento heredado más grave: pueden quedar expuestos todos los métodos públicos. Desde API 17 se exige @JavascriptInterface, pero la anotación no vuelve seguro el contenido no confiable.

Mantén el puente fuera de páginas no confiables

RIESGOSO — puente y navegación no confiable en el mismo WebView
webView.addJavascriptInterface(
  NativeBridge(), "Android"
)
webView.loadUrl(untrustedUrl)
MÁS SEGURO — separar contenido confiable y no confiable
// Este WebView se reserva para la interfaz empaquetada y controlada por la app.
trustedWebView.settings.javaScriptEnabled = true
trustedWebView.addJavascriptInterface(
  NativeBridge(), "Android"
)
trustedWebView.loadUrl("file:///android_asset/index.html")

// Otro WebView gestiona páginas remotas o controladas por usuarios.
untrustedWebView.removeJavascriptInterface("Android")
untrustedWebView.settings.javaScriptEnabled = false
// Valida HTTPS y una lista permitida explícita de hosts.
untrustedWebView.loadUrl(validatedHttpsUrl)

El límite más sólido es arquitectónico: nunca navegues desde un WebView con puente a una página remota, creada por usuarios o influida por un atacante. Si es inevitable cargar contenido no confiable, elimina la interfaz antes de cargarlo y usa otro WebView con JavaScript desactivado salvo que sea necesario. Android indica que el objeto inyectado está disponible para todos los frames y que la eliminación surte efecto tras la siguiente carga de página. HTTPS protege el transporte; no convierte en confiables al host ni a su contenido. Valida tanto el esquema como el host de la URL y abre en el navegador del sistema los enlaces fuera de la lista permitida. Limita los métodos del puente, valida cada argumento y aplica la autorización en código nativo sin confiar en la página que llama.

Preguntas frecuentes sobre la seguridad del puente de WebView

¿API 17 o posterior hace que addJavascriptInterface sea seguro?

No. API 17+ limita la exposición a métodos públicos anotados con @JavascriptInterface; no verifica el origen del frame ni convierte en confiable el contenido controlado por un atacante. Mantén el puente en un WebView que solo cargue contenido controlado por la app.

Referencias

Véase también Cross-Site Scripting (XSS, CWE-79): cómo funciona y cómo evitarlo en cada lenguaje — flawopen.com Protección XSS de Angular: valores seguros y APIs de omisión XSS por MIME sniffing: Content-Type y nosniff CSP y escape de salida: ¿necesitas ambos? ¿Es seguro dangerouslySetInnerHTML en React? ¿DOMPurify basta para proteger innerHTML? ¿Markdown es seguro frente a XSS?