Un WebView ejecuta el contenido web con todos los privilegios de la app host, y el puente de JavaScript es una superficie de escalada de privilegios sin muros. En Android, addJavascriptInterface inyecta un objeto Java en cada frame —incluidos los iframes— sin forma de verificar el origen del llamador; antes de Android 4.2 era ejecución remota de código directa, y hoy un puente amplio más contenido reflejado sigue siendo XSS que ejecuta código nativo con los permisos de tu app. web.dev confirma que WebView no tiene aislamiento de sitio real y entrega al host tus cookies y tu DOM. En 2026, CVE-2026-103922 (Capacitor, CVSS 9.6) mostró el fallo del límite de mismo origen en una app híbrida en producción. Un runtime propio del host traza el muro: mínimo privilegio, por origen, con control de capacidades.

El puente confía en quien lo llame

El puente nativo es la puerta entre la web y lo nativo, y por defecto está abierta. addJavascriptInterface de Android expone un objeto Java a cada frame del WebView, incluido cualquier iframe, y la propia plataforma advierte que no hay mecanismo para verificar el origen del frame que llama. La consecuencia es directa: inyecta un frame malicioso en una página legítima y ese frame puede invocar tus métodos nativos. Las apps orientadas a API 16 o anterior podían ser controladas por completo por JavaScript; incluso hoy, reflejar contenido de usuario no confiable en un WebView con puente habilitado es una ruta de XSS que ejecuta Java con los permisos de la app host —escalada de privilegios, no un fallo menor. Los puentes basados en MessageChannel solo son más seguros si añades tú la verificación de origen; sin ella, se aceptan mensajes de cualquier remitente.

Sin aislamiento de sitio no hay muros reales

Un navegador reforzado separa las páginas no confiables en procesos aislados para que una pestaña no lea las cookies ni la memoria de otra. WebView no es eso. Según web.dev, antes de Android 8.0 el renderizador corría en el mismo proceso que la app, y aun en sistemas nuevos todas las páginas y todas las instancias de WebView siguen compartiendo un único proceso —el aislamiento de sitio real es imposible. Eso es lo que expuso miles de millones de dispositivos a Meltdown y Spectre: una página maliciosa podía intentar leer datos de origen cruzado que nunca debería ver. WebView también entrega al host acceso completo al contenido renderizado, incluidas las cookies y el DOM, y carece de los indicadores de seguridad de un navegador real —la barra de direcciones que ve el usuario puede no coincidir con la página mostrada, incluso sobre HTTPS, sin API para detectarlo.

Una brecha de 2026 lo hizo real

No es teoría. En 2026, Capacitor —un framework híbrido muy usado— publicó CVE-2026-103922, con puntuación CVSS 9.6. Su guarda de navegación verificaba el esquema y el host de la URL pero no su ruta, así que un enlace manipulado podía alcanzar un endpoint proxy interno servido en el origen propio de la app. La capa nativa entonces obtenía contenido controlado por el atacante y lo devolvía bajo el origen confiable de la app, permitiendo que JavaScript malicioso corriera con privilegios de mismo origen —leyendo localStorage, cookies y cualquier capacidad nativa expuesta por plugins registrados. Corresponde a CWE-346 (error de validación de origen) y CWE-441 (confused deputy). Desactivar el plugin HTTP no sirvió, porque el manejador seguía disponible. Un enlace normal, renderizado dentro de la app, se convirtió en una ruta de ejecución de scripts con toda la confianza de la app.

La solución del runtime

Un runtime propio del host trata a la web como no confiable por defecto y traza un límite de seguridad explícito. El puente es por origen y de mínimo privilegio: una página de una entrada de catálogo no confiable no puede alcanzar un manejador de credenciales o de dispositivo, solo las capacidades que el host concede explícitamente. Los contextos web se aíslan por entrada, la navegación se verifica frame a frame, y la capa nativa comprueba, en lugar de confiar, cada llamada. El muro se escribe en una política, no se deja a un defecto que confía en quien llame.

DimensiónWebViewRuntime propio del host
Exposición del puenteObjeto Java en cada frame, sin origenPor origen, mínimo privilegio, control de capacidades
Aislamiento de procesoProceso único compartido, sin aislamientoContexto web aislado por entrada de catálogo
Robo de origen cruzadoExposición tipo Meltdown/SpectreLa capa nativa verifica cada llamada
Indicadores de seguridadNinguno; la barra puede no coincidirControlado por el host, confianza verificable
Límite de mismo origenConfiable por defecto (CVE-2026-103922)Explícito, forzado por origen

El hilo de esta serie siempre vuelve a una palabra: control. Un WebView confía en la web que carga y le entrega los privilegios de la app; el límite falla en silencio y, como mostró 2026, de forma catastrófica. Un runtime convierte el límite en un muro que construyes —por origen, por capacidad, por página—. Para un catálogo de páginas de terceros que transan dentro de tu app, ese muro es la diferencia entre una plataforma y un pasivo.

Fuentes