本节摘要:Wasm 的安全模型常被一句"天然沙箱"带过,这是危险的偷懒——规范给的是地基,防线要在部署里一层层砌。本节把纵深防御的每一层落成可配置的实践:验证与隔离的语义保证、资源限额的攻防配置、侧信道风险的坦率交代,以及 Web 平台的隔离响应头。旧版"安全与性能挑战"的内容并入本节。
别以为"字节经过验证"就等于"模块绝对安全"——验证器保证的是语义合法,不保证行为无害:一段完全合法的字节也可以写死循环吃满 CPU、申请内存直到宿主窒息、用计时器侧信道偷窥邻居。本节的任务是把安全从规范语义延伸到部署治理,四层防线一层层砌。
第一层是验证隔离,规范给的:类型检查、结构化控制流、内存边界、陷阱语义(第二、三章),保证畸形字节进不来、越界访问出不去。第二层是能力隔离,WASI 给的:系统能力显式授予(第六章),清单之外不可见。第三层是资源隔离,部署方给:本节重点。第四层是平台隔离,宿主环境给:浏览器的跨源隔离、服务端操作系统的用户与命名空间。四层缺一不可——只信第一层的团队,等于把整栋楼的安全押在门禁上。

资源攻击的麻烦在于模块完全合法——验证器放行、能力清单合规,只是行为贪婪。防线因此全部落在宿主配置上,四项基本限额要成为默认动作。
内存上限:实例化时锁死最大页数,超限在申请页时陷阱,而不是让宿主 OOM。执行配额:给指令执行计费,超限即中断——主流引擎都提供了相应机制(燃料计费或时间片检查),对处理外部输入的插件场景这是保命项。栈深限制:防深度递归打爆原生栈。实例数上限:多租户环境按租户配额回收实例,防累积蚕食。
$ wasmtime run \ --wasm max-mem-size=268435456 \ # 内存上限 256 MiB --wasm max-epochs=10000 \ # 执行配额:可被中断的计费单元 handler.wasm
配置哲学与能力清单一致:默认收紧、显式放开。第三方的处理插件给十兆内存加秒级配额足够,自家的编解码内核再按需放宽——限额越低,爆炸半径越小。
侧信道值得单独坦率交代,因为它是 Wasm 安全叙事里最常被夸大也最常被忽视的部分。夸大在于:验证语义确实堵住了内存不安全类攻击的绝大多数面——越界读写、类型混淆、控制流劫持在 Wasm 里结构性不存在,Spectre 类漏洞的"幽灵指令"路径在验证层就被大幅收窄。忽视在于:侧信道的本质是"时间差泄露信息",这条通路 Wasm 并没有堵——共享线程计时器、缓存行竞争的时序差异,理论上都能被恶意模块用于推断共享环境里的其他信息。
务实的应对按威胁模型分层:互不信任的代码不共池——恶意插件与敏感业务不放进同一个引擎进程,隔离靠实例边界而非指望计时器;削计时器精度——把高精度时间从能力清单里拿掉或做模糊化,抬高侧信道的信噪比门槛;关键路径加噪声——对确实敏感的共享环境,在调度层引入随机延迟。三条都不是银弹,组合起来足以让绝大多数侧信道攻击在经济上不划算——安全工程的目标从来是"贵到没人干",不是"数学上不可能"。
浏览器端的部署安全集中在两个响应头策略上。跨源隔离(COOP 与 COEP,第五章部署门槛的攻防面)把页面关进独立的浏览上下文组,SharedArrayBuffer 因此可用——它的另一面是:启用后第三方嵌入内容也必须配合隔离头,广告与嵌入式组件的兼容性要提前排查。内容安全策略要对 Wasm 显式放行:脚本的 eval 限制默认波及模块编译,需要加 Wasm 专用标记——最小化放行面,只给确实需要编译模块的路径。
| 威胁 | 防线位置 | 配置要点 |
|---|---|---|
| 畸形字节 | 验证器 | 无需配置,语义保证 |
| 越权系统访问 | WASI 能力清单 | 默认全关,逐项授予 |
| 资源耗尽 | 宿主限额 | 内存、配额、栈深、实例数四件套 |
| 侧信道窥探 | 部署架构 | 代码分池、计时器降精度 |
| 跨线程数据竞争 | 共享内存协议 | 隔离头加 Atomics 纪律 |
| 依赖投毒 | 供应链治理 | 见上一节清单,可重现构建兜底 |
资源限额里最精巧的是执行配额,值得拆开看它如何做到"跑不完整也能被叫停"。字节码是分段执行的,引擎在译码循环与函数调用边界处埋有检查点;配额机制在每个检查点扣减额度,额度耗尽就抛出可捕获的中断——恶性循环再紧密,也逃不过指令粒度的检查。这是字节码相对原生代码的独特治理优势:原生代码想强停一个死循环只能杀线程,字节码可以精确、体面、可观察地中断。
理解了这一点,限额配置就能对症下药:批处理任务给大额度、交互请求给小额度、来源不明的插件按最坏情况给。额度耗尽的表现形式也要与业务约定——宿主把它转成业务层的服务不可用响应,而不是让调用方看到引擎内部的中断语义。安全机制落到产品里,最后一公里永远是错误呈现的设计。
安全配置的最后一步是把它写成代码:限额、能力清单、隔离头,全部落进部署清单与基础设施代码,与业务代码一起评审、一起版本化。口头安全策略会随人员流动蒸发,代码化的安全策略才能在每一次部署中自动兑现——这是把第八章的精神接回第三章确定性传统的最后一环。
信号系统砌好,下一节是行车手册:工程化的最佳实践,以及当前工具链的局限清单。