WebView 以宿主 App 的全部权限运行 Web 内容,而 JavaScript 桥是一处没有围墙的提权面。Android 上 addJavascriptInterface 把 Java 对象注入每个帧(含 iframe),却无法核验调用方的来源;Android 4.2 之前它是赤裸裸的远程代码执行,今天「宽泛的桥 + 被反射的不可信内容」仍是能以宿主权限跑原生代码的 XSS。web.dev 确认 WebView 没有真正的站点隔离,并把 Cookie 与 DOM 双手奉给宿主。2026 年 CVE-2026-103922(Capacitor,CVSS 9.6)在已上线的混合 App 里演示了这个同源边界的失守。宿主自有 runtime 把墙画出来:最小权限、按来源作用域、按能力设闸。
桥信任每一个调用方
原生桥是 Web 与原生之间的那扇门,而默认情况下它是没锁的。Android 的 addJavascriptInterface 把一个 Java 对象暴露给 WebView 的每一个帧,包括任何 iframe,平台自己也承认「没有机制核验调用帧的来源」。含义很直接:往一个合法页面里注入一个恶意帧,那个帧就能调用你的原生方法。以 API 16 及更早为目标的应用,JavaScript 可以完全控制宿主 App;即便今天,把不可信的用户内容反射进一个启用桥的 WebView,就是一条以宿主权限执行 Java 的 XSS 路径——这是提权,不是小毛病。基于 MessageChannel 的桥只有你自己加上来源校验才更安全;不加,任何发送者发来的消息都会被接受。
没有站点隔离,就没有真正的墙
一个经过加固的浏览器会把不可信页面分隔进互相隔离的进程,让一个标签页读不到另一个的 Cookie 或内存。WebView 不是这样。据 web.dev,在 Android 8.0 之前渲染进程与宿主 App 同进程运行,而即便在更新的系统上,所有页面与 WebView 实例仍共享单一进程——所以真正的站点隔离不可能实现。这正是让数十亿设备暴露在 Meltdown 与 Spectre 之下的原因:一个恶意页面可以尝试读取它本不该看到的跨源数据。WebView 还把渲染内容的完全访问权(包括 Cookie 和 DOM)交给宿主 App,且缺少真实浏览器提供的安全 UI 指示器——用户看到的地址栏可能与实际显示的页面不一致,甚至发生在 HTTPS 连接上,而且没有 API 能发现它。
2026 年的真实失守
这不是理论。2026 年,主流混合框架 Capacitor 爆出 CVE-2026-103922,CVSS 9.6。它的 WebView 导航守卫校验了目标 URL 的 scheme 和 host,却没校验路径,于是构造的链接可以命中一个以应用自身来源托管的内部代理端点。原生层随后拉取攻击者控制的内容,并以应用的受信来源返回,让恶意 JavaScript 以同源权限运行——读取 localStorage、Cookie,以及已注册插件暴露的任何原生能力。它对应 CWE-346(来源校验错误)与 CWE-441(混乱 Deputy)。即便禁用 HTTP 插件也无济于事,因为那个处理器始终在线。一条普通的链接,在 App 内渲染,就成了带着 App 全部信任的脚本执行通道。
runtime 解法
宿主自有 runtime 默认把 Web 当作不可信对象,并画出一条显式的安全边界。桥按来源作用域、最小权限:一个来自不可信 catalog 条目的页面够不到凭据或设备处理器,它只能拿到宿主显式授予的能力。Web 上下文按条目沙箱化,导航逐帧校验,原生层检查而非信任每一次调用。墙是写进策略里的,而不是留给一个「谁来敲都信」的默认。
| 维度 | WebView | 宿主自有 runtime |
|---|---|---|
| 桥暴露面 | Java 对象注入每帧,无来源校验 | 按来源作用域、最小权限、按能力设闸 |
| 进程隔离 | 单一共享进程,无站点隔离 | 按 catalog 条目沙箱化 Web 上下文 |
| 跨源窃取 | Meltdown/Spectre 级别暴露 | 原生层逐项校验每次调用 |
| 安全指示器 | 无;地址栏可能与页面不符 | 宿主可控、可核验的信任 |
| 同源边界 | 默认受信(CVE-2026-103922) | 显式、按来源强制 |
本系列始终绕不开一个词:控制权。WebView 信任它加载的 Web,并把 App 的权限双手奉上;边界静默失守,而 2026 年告诉我们,它会以灾难性方式失守。runtime 把边界变成一堵由你修筑的墙——按来源、按能力、按页面。对一套承载第三方页面在你的 App 里交易的 catalog 来说,这堵墙,就是「平台」与「负债」的分界线。
参考来源
- Android 开发者——不安全的 WebView 原生桥:addJavascriptInterface 注入每帧、无来源校验;API 17 前为 RCE,反射内容是带宿主权限的 XSS — 官方把桥定性为提权面。
- web.dev——Android 上的 Web:WebView 无多进程架构与站点隔离;单一共享进程;可完全访问 Cookie/DOM;无安全 UI 指示器 — WebView 不是加固浏览器的结构性根因。
- CVE-2026-103922(Capacitor),CVSS 9.6——导航守卫漏掉 URL 路径;App 同源内部代理让远程内容以同源信任运行(CWE-346、CWE-441) — 2026 年混合 App 因缺失边界而失守。
- Android 开发者——通过 JS 桥访问原生 API:安全等级 addWebMessageListener(白名单)高于 addJavascriptInterface(无来源校验) — 为何默认桥是最弱的一档。
- OWASP MASTG——平台交互与 WebView 桥风险(MASVS-PLATFORM) — 桥与剪贴板加固对应到移动安全要求。