概述
WebAssembly的安全模型是其成为AI Agent安全执行环境的核心基础。与传统容器或VM隔离不同,WASM提供数学可验证的沙盒化和能力安全模型。1
核心安全特性
| 特性 | 描述 | 防护目标 |
|---|---|---|
| 线性内存隔离 | 每个模块拥有私有线性内存 | 防止内存越界访问 |
| 结构化控制流 | 验证所有间接调用目标 | 防止控制流劫持 |
| 能力安全模型 | 资源访问需要显式授权 | 防止权限提升 |
| 无环境权限 | 默认无文件系统/网络/时钟访问 | 最小权限原则 |
沙盒机制详解
线性内存隔离
WASM的内存模型是Wasm线性内存(Linear Memory),所有加载/存储操作都经过动态边界检查:
┌─────────────────────────────────────────────────┐
│ Wasm Module Memory │
├─────────────────────────────────────────────────┤
│ 0x0000 │ Protected Region 1 │ │
├─────────────────────────────────────────────────┤
│ │ Module's Private │ │
│ │ Linear Memory │ │
├─────────────────────────────────────────────────┤
│ 0xFFFF │ Boundary Check │ → Trap on OOB │
└─────────────────────────────────────────────────┘
每个模块的内存操作:
- 边界检查:每次load/store执行动态边界验证
- 私有内存:模块间不共享内存,无法直接跨模块访问
- 数学验证:内存安全可被形式化验证
结构化控制流与CFI
WASM验证器确保所有间接调用目标都是类型兼容的函数:
;; 间接调用表必须声明类型
(type $fn_type (func (param i32) (result i32)))
(table 2 2 (type $fn_type))
(elem 0 $func_a $func_b) ;; 表项必须是有效函数**控制流完整性(CFI)**保证:
- 间接调用只能跳转到表中的有效函数
- 无法利用类型混淆进行控制流劫持
能力安全模型(Capability-Based Security)
核心原则
WASM从零环境权限开始。新实例化的模块可以计算,但无法:
- 打开文件
- 建立网络连接
- 派生进程
- 查询系统时钟
- 生成随机数
每个能力必须由host在实例化时显式授予。2
WASI能力模型
WASI实现能力令牌模型:目录句柄传递给模块只授予该子树的访问权限,而非整个文件系统。
// 默认:无任何权限
let capabilities = Capabilities::none();
// 仅授予只读filesystem权限
let capabilities = Capabilities::none()
.with_filesystem_read(vec!["/data/public".to_string()]);
// 授予HTTP权限(限特定端点)
let capabilities = Capabilities::none()
.with_http(HttpCapability::new(vec![
EndpointPattern::host("api.example.com")
.with_path_prefix("/v1/")
]));资源类型(Resource Types)
WASI 0.2+引入资源类型,实现细粒度权限控制:
interface blob-store {
resource blob {
read: func() -> list<u8>;
write: func(data: list<u8>);
}
create-blob: func() -> blob;
}组件持有资源的引用,但无法直接访问底层内存。资源句柄是不可伪造的能力令牌。
AI Agent安全执行
威胁模型
2026年AI Agent面临的主要威胁:
| 威胁类型 | 描述 | WASM防护 |
|---|---|---|
| Prompt注入 | 恶意指令导致Agent执行未授权操作 | 能力边界限制 |
| 代码执行 | Agent生成有害代码 | 沙盒隔离 |
| 数据泄露 | Agent尝试访问未授权数据 | 能力访问控制 |
| 资源耗尽 | 恶意Agent消耗系统资源 | 燃料计量/Fuel Metering |
Session-Governor-Executor架构
WASM非常适合SGE隔离域模型:
┌─────────────────────────────────────────────────────────┐
│ Agent Runtime │
├─────────────────────────────────────────────────────────┤
│ ┌─────────────────────────────────────────────────┐ │
│ │ Governor (Wasmtime Host) │ │
│ │ - 能力策略配置 │ │
│ │ - 资源限制(燃料/内存) │ │
│ │ - 审计日志 │ │
│ └─────────────────────────────────────────────────┘ │
│ │ │
│ ┌─────────────┼─────────────┐ │
│ ▼ ▼ ▼ │
│ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ │
│ │ Executor A │ │ Executor B │ │ Executor C │ │
│ │ (Wasm A) │ │ (Wasm B) │ │ (Wasm C) │ │
│ │ 工具:只读 │ │ 工具:网络 │ │ 工具:邮件 │ │
│ └─────────────┘ └─────────────┘ └─────────────┘ │
└─────────────────────────────────────────────────────────┘
关键属性:
principal × trust_level × purpose决定能力集- 即使Agent会话被攻陷,也无法访问未授权资源
- 能力集在组件实例化时确定,运行期间不可变更
Microsoft Wassette
Microsoft的Wassette(2025年8月)是将WASM隔离与能力安全结合用于AI Agent沙盒化的典型实现:
// 每个工具是WASM模块,仅持有完成任务所需的能力
let tool_config = WasmToolConfig {
// 读金融数据工具:只读文件系统
filesystem: Some(ReadOnlyDir "./market-data/"),
// 无网络权限
network: None,
// 无时钟权限
clock: None,
};硬件辅助安全
SGX与ARM MTE
现代WASM部署结合硬件隔离技术:
| 技术 | 厂商 | 机制 |
|---|---|---|
| SGX | Intel | Enclave隔离,内存加密 |
| ARM MTE | ARM | 标签化内存,检测use-after-free |
| CHERI | Arm/Morello | 能力硬件强化,硬件能力边界 |
cWAMR项目
cWAMR是首个将CHERI硬件能力模型与WASM运行时集成的项目:
- cWASI:通过CHERI密封引用调解所有系统调用
- 能力感知内存分配器:防止内存越界
- 安全externref处理:防止对象引用泄露
资源限制(Resource Limits)
燃料计量(Fuel Metering)
CPU使用通过Wasmtime的燃料系统限制:
const DEFAULT_FUEL_LIMIT: u64 = 100_000_000; // 约1秒典型CPU
let config = WasmRuntimeConfig {
fuel_config: FuelConfig {
limit: DEFAULT_FUEL_LIMIT,
enable_metrics: true,
},
memory_limit_mb: 10, // 默认10MB内存限制
};内存与执行时间
| 限制类型 | 典型值 | 触发条件 |
|---|---|---|
| 内存上限 | 10-128MB | OOM时Trap |
| 燃料限制 | 100M-1B | 燃料耗尽时Trap |
| 执行超时 | 30s-5min | Epoch interruption |
| 调用深度 | 1024 | 栈溢出Trap |
已知限制与缓解
瞬态执行攻击
Spectre类攻击可在WASM沙盒内发起:
| 攻击类型 | 缓解措施 |
|---|---|
| Spectre v1 | Wasmtime使用软件防护机制 |
| Spectre v2 | 浏览器隔离 + site isolation |
| 侧信道 | 定时信道防护,秘密清除 |
当前限制
- 资源隔离不完美:CPU/内存竞争需通过host层面控制
- 调试工具不足:跨语言组件调试困难
- GC语言支持:依赖运行时增加攻击面
生产安全实践
零信任原则
// 1. 否认所有(deny-by-default)
let capabilities = Capabilities::none();
// 2. 按需授权(least privilege)
capabilities
.with_http(target_host_only)
.with_workspace_read(specific_paths_only);
// 3. 凭证从不注入WASM
// 凭证在host边界解密,仅对匹配host注入泄漏检测
// 响应扫描所有输出
let leak_detector = LeakDetector::new();
if leak_detector.contains_secret(&response) {
return Err(SecurityError::SecretExfiltration);
}