有一种风险不会出现在任何路线图里。一个消费类 App 内嵌第三方 H5 来交付服务——支付、借贷、保险。页面能用。但在你 App 里跑的那段代码,是你没写、读不懂、也拦不住它会改的黑盒。如果那个盒子漏了用户的卡号,或者挂了个钓鱼表单,或者传输中被篡改,监管和用户都会找上门——找的是你,不是服务商。
我参加过足够多的事故复盘,知道这戏怎么演。宿主扛着品牌、牌照和法律责任;内嵌页什么都不扛,而且从没被设计来扛。
为什么 H5 天生不透明
webview 里的 H5 执行的是服务商源站上的代码。你控制不了它的内容、依赖,也控制不了它的更新节奏。服务商可以凌晨两点推一个新包,你的 App 一小时后就在跑它。没有你要校验的签名,没有你这边的审核关,也没有一份它拉了哪些脚本的清单。
这种不透明恰恰是安全框架点名的第一类风险。OWASP 的 Mobile Top 10 把「代码质量薄弱」和「代码篡改」列为头号移动风险;而 XSS——那个经典的 Web 攻击——天生就活在一个 H5 面里,因为它毕竟就是个网页。webview 并不会把页面从它自己身上隔离出来——它跑的是源站喂来的任何东西。
合规暴露是具体的,不是理论。碰卡号的支付流程受 PCI DSS 约束,它要求你知道卡数据去了哪、并限制它。大多数司法辖区里的金融 App 要对一个要求「对处理客户数据的每个组件都有控制证据」的监管负责——欧盟的 DORA(数字运营弹性法案,2022/2554)把运营弹性和第三方风险变成了董事会级别的义务。当那个高风险组件是你审计不了的第三方 H5,你只能用「我们信任他们」来回答这些问题。
摆到桌面上
| 维度 | 内嵌第三方 H5 | 小程序 runtime(宿主管控) |
|---|---|---|
| 代码可见性 | 不可审计的第三方源站 | 签名、审核过的包 |
| 更新控制 | 服务商随意推送 | 宿主把关每次发布 |
| 攻击面 | XSS、篡改、钓鱼 | 沙箱隔离、能力受限 |
| 支付数据 | 难约束 | 宿主强约束边界 |
| 监管姿态 | 「我们信任供应商」 | 第一方、有证据的控制 |
| 事件响应 | 甩锅、慢 | 宿主可即时下架 |
差别在于控制时延。用 H5,你对一个坏包最快的响应是慌忙打电话给服务商。用 runtime,宿主签名、审核,并且能在几分钟内把不合规的包从目录里拽下来。这道差距,就是「你管理的事故」和「管着你的事故」之间的差别。
runtime 不会让安全免费。宿主仍要对引擎、审核流水线、runtime 自身的加固负责。但它把一个不透明的第三方面,变成了一个你真正治理的面:签名包、分级 API、能力白名单、以及你掌控的下架权。黑盒变成了玻璃盒。
诚实的话:如果你的 App 碰钱、碰健康或碰身份,「我们内嵌了个网页」不是一个站得住脚的架构。一个可控的 runtime,才把那份暴露从你继承来的负债,变成你拥有的控制。