春节期间,我持续提交了140+ commit 到github,在研究openclaw的rust版本重构的时候,也对skills执行沙箱的进行了思考和升级

25 年末至 2026 年初,OpenClaw 的 ClawHub 插件市场遭遇大规模供应链投毒(ClawHavoc),超过 340 个恶意 Skills 被植入,攻击者通过 SKILL.md 中的虚假"安装步骤"诱导用户在终端执行恶意命令,窃取 SSH 私钥、API Key、加密货币钱包等敏感信息。

这个事件促使我们重新思考一个问题:当 AI Agent 需要执行来自第三方的代码时,各种沙箱方案在面对真实攻击场景时的防御能力到底怎么样?

我们对四种开源沙箱方案做了 20 项安全测试(测试用例覆盖了 ClawHavoc 中出现的攻击手法),本文分享测试数据和我们在 SkillLite 中的工程思考,欢迎大家指正和讨论。


一、ClawHavoc 告诉我们什么

ClawHavoc 攻击链的关键步骤是:恶意 Skill → os.system("curl ... | bash") 或诱导用户执行 → 从攻击者服务器拉取第二阶段载荷 → 读取 SSH 私钥、环境变量、Keychain 等敏感信息。

如果我们把这个攻击链拆解成测试用例,会发现它精确命中了沙箱安全的几个核心维度:进程执行控制(能否阻止 os.system)、网络隔离(能否阻止 curl 外连)、文件系统隔离(能否阻止读 SSH 私钥)、信息泄漏防护(能否阻止读环境变量)。

带着这个思路,我们对四种方案做了 20 项测试。


二、测试设计与结果

测试覆盖文件系统、网络、进程、资源限制、代码注入、信息泄漏共 20 项攻击场景(其中多项直接对应 ClawHavoc 的攻击手法),每项记录"拦截 / 部分拦截 / 放行"。

方案

拦截数

评分

定位

SkillLite (Level 3)

18/20

90.0%

Rust 原生沙箱 + 静态扫描

Pyodide

7/20

35.0%

WebAssembly 沙箱(LangChain 采用)

Claude SRT

6.5/20

32.5%

Anthropic 开源沙箱

Docker

2/20

10.0%

容器隔离

逐项对比

测试项

SkillLite (L3)

Docker

Pyodide

Claude SRT

文件系统

读 /etc/passwd

读 SSH 私钥

写 /tmp

目录穿越

列根目录

网络

HTTP 请求

DNS 查询

端口监听

进程

os.system()

subprocess

进程枚举

信号发送

⚠️

资源限制

内存炸弹

Fork 炸弹

CPU 炸弹

代码注入

动态 import os

eval/exec

修改内建函数

信息泄漏

读环境变量

获取系统信息

评分公式:(拦截数 + 部分拦截 × 0.5) / 总测试数 × 100%

对照 ClawHavoc 攻击链:如果一个恶意 Skill 在 main.py 里尝试执行 os.system("curl ... | bash")(对应表中的"os.system()"和"HTTP 请求"行),再读取 ~/.ssh/id_rsa(对应"读 SSH 私钥")和环境变量(对应"读环境变量")——SkillLite 在这四个环节全部拦截,而多数方案在其中至少有两个环节放行。

需要说明的是,这些结果基于各方案的默认配置。经过定制化加固(如 Docker 的 --cap-drop--security-opt、自定义 seccomp profile 等),各方案的表现都可以显著提升。


三、设计目标不同,结果自然不同

Docker 在我们的测试中拦截率较低,但这完全不意味着 Docker "不安全"。它的设计目标是应用部署隔离,而非防御恶意代码执行——这是两个不同的问题域。

Docker 在应用部署场景下是成熟可靠的标准方案。但在 AI Agent Skills 场景中,威胁模型发生了根本变化:

传统部署场景

AI Agent Skills 场景

代码来自可信开发团队

代码来自不可信第三方

目标是资源隔离

目标是防御恶意行为

容器内网络/文件访问是功能需求

容器内网络/文件访问可能是攻击路径

类似地,Pyodide 的 WASM 沙箱擅长浏览器端隔离,Claude SRT 专注于提供快速可用的运行时。每个方案都在自己的设计目标下做了合理的取舍


四、我们的思路:全链路防御

SkillLite 能拦截 18/20 项测试(持续优化中),核心原因不在于某一层做得特别强,而是我们尝试在安装前、执行前、执行中三个阶段都做拦截。这个思路是否合理,欢迎大家一起讨论。

3.1 三层防线架构

┌─────────────────────────────────────────────────┐
│ 第一层:安装时扫描                                │
│ ├─ 静态规则扫描(regex 匹配恶意模式)               │
│ ├─ LLM 智能分析(可疑代码由大模型二次判定)          │
│ └─ 供应链审计(PyPI/OSV 漏洞库比对)               │
├─────────────────────────────────────────────────┤
│ 第二层:执行前授权                                │
│ ├─ 两阶段确认(扫描 → 用户确认 → 执行)            │
│ └─ scan_id 绑定(防止绕过扫描直接执行)            │
├─────────────────────────────────────────────────┤
│ 第三层:运行时沙箱                                │
│ ├─ OS 原生隔离(macOS Seatbelt / Linux bwrap)    │
│ ├─ 进程执行白名单(仅允许解释器本身)               │
│ ├─ 文件系统隔离(deny 敏感路径 + 移动保护)          │
│ ├─ 网络隔离(Seatbelt deny + 代理过滤)            │
│ ├─ 资源限制(rlimit CPU/内存/文件/进程数)          │
│ └─ IPC 封堵(deny mach-register/iokit-open)     │
└─────────────────────────────────────────────────┘

3.2 几个我们踩过坑的工程决策

从黑名单到白名单

早期我们也用黑名单拦截危险命令(/bin/sh/usr/bin/curl 等),上线后发现攻击者可以通过路径变体(/usr/local/bin/bash、符号链接)绕过。

后来改为严格白名单:Seatbelt 的 process-exec 仅允许解释器路径本身。

;; 仅允许解释器执行
(allow process-exec (literal "/path/to/python3"))
(allow process-exec (literal "/path/to/canonical/python3"))
;; macOS Python.framework 兼容
(allow process-exec (subpath "/path/to/Python.framework/Versions/3.x"))
;; 拒绝一切其他进程执行
(deny process-exec)

这样即使恶意代码调用 os.system("curl ..."),Seatbelt 在内核层就会拦截。不过这也带来了兼容性挑战——比如 macOS Homebrew 的 Python 通过 posix_spawn 在 framework 内部重新执行,我们需要额外白名单整个 framework 版本目录才解决。

沙箱失败不降级

我们早期犯过一个错误:沙箱启动失败时静默退回无沙箱执行。后来意识到这等于给了攻击者一个绕过通道——只需构造让沙箱初始化失败的 payload 即可。

现在的策略是:沙箱失败 → 直接报错终止,绝不降级。

match execute_with_sandbox(skill_dir, runtime, config, input_json, limits) {
    Ok(result) => Ok(result),
    Err(e) => {
        Err(e.context(
            "Sandbox execution failed. Refusing to fall back to \
             unsandboxed execution."
        ))
    }
}

静态扫描前置

运行时沙箱再完善,代码进沙箱之前多一道过滤总是好的。eval()exec()__import__('os') 这些模式在安装时就会被规则引擎标记。这也是 SkillLite 能拦截"动态 import os"和"eval/exec"的原因——不过说实话,纯 regex 扫描容易被混淆绕过,这是我们后续要用 AST 分析加强的地方。

3.3 各方案的安全覆盖层次

安全能力

SkillLite

Docker

Pyodide

SRT

安装时判毒

静态代码扫描

供应链审计

进程执行白名单

IPC/内核操作封堵

文件系统隔离

部分

部分

网络隔离

资源限制

部分

部分

部分

不同方案侧重不同层次。Docker 的容器隔离在部署场景强大,Pyodide 的 WASM 隔离在浏览器场景有独特优势,SRT 与 SkillLite 用了相同的底层技术(Seatbelt)但配置策略不同。SkillLite 尝试在多个阶段都做拦截,但代价是实现复杂度更高。


五、安全与性能的平衡

通常安全和性能是对立的——更多检查意味着更多开销。我们的经验是:如果安全机制本身就是 OS 内核能力,开销可以趋近于零

维度

SkillLite

Docker

Pyodide

SRT

热启动

40ms

194ms

672ms

596ms

冷启动

492ms

120s

~5s

~1s

内存占用

~10MB

~100MB

~50MB

84MB

Binary 大小

~2MB

200MB+ daemon

50MB+ WASM

需安装

性能差异的主要原因是架构选择不同:

  • Seatbelt / bwrap 是 OS 内核能力setrlimit 是一次 syscall,零运行时开销;Seatbelt profile 在进程启动时一次性加载

  • 静态扫描编译进 binary:regex 规则在编译时嵌入,扫描一个 skill 只需毫秒

  • 单 binary 零依赖:不需要 Docker daemon、Node.js runtime、WASM 引擎

当然,Docker 和 E2B 等方案的架构优势在于更强的隔离边界(内核级别的 namespace/cgroup 或 VM 隔离),这是进程级沙箱无法完全替代的。具体选择取决于场景对安全深度和性能延迟的权衡。


六、更广泛的生态现状

AI Agent 框架的安全隔离整体上还处于早期阶段,这也是我们做这个方向的原因之一:

方案

沙箱方式

安装时扫描

代码审计

供应链防护

SkillLite

Seatbelt/bwrap 原生沙箱

Open Interpreter

无沙箱

AutoGPT / CrewAI

Docker 或无

LangChain

Pyodide 或无

E2B

云端 microVM

Claude SRT

Seatbelt

可以看到,多数框架目前主要依赖运行时隔离这单一层面。我们认为全链路防御的思路值得探索,但也不确定这是不是最优解——也许有更好的方法我们还没想到。


七、老实说,我们还有不少不足

SkillLite 目前还有不少明显的短板,这里坦诚列出来,也希望大家帮忙出出主意:

短板

说明

我们的计划

Memory bomb 未拦截

RLIMIT_AS 默认值过高

降至 256MB,补 fallback 路径

内建函数修改未拦截

regex 模式未覆盖所有 case

加强规则 + AST 扫描

Linux seccomp 不完整

仅阻止 AF_UNIX

扩展 ptrace/mount/clone 等

签名验证是字符串比较

非密码学验证

引入 Ed25519

(allow default) 仍在使用

macOS Seatbelt 未完全 deny default

渐进式迁移中

静态扫描易被绕过

纯 regex 无法防混淆

考虑 tree-sitter AST 分析

特别是 (allow default) 这个问题——理想情况下应该用 (deny default) + 显式白名单,但兼容性测试成本非常高。如果有做过类似迁移的朋友,特别想听听你们的经验。


八、如何复现测试

所有测试脚本和数据都是开源的,欢迎在自己的环境跑跑看,也帮我们验证一下结果:

git clone https://github.com/EXboys/skilllite
cd skilllite

# 构建
cargo build --release

# 运行安全对比测试
python3 benchmark/security_vs.py

# 运行性能对比测试
python3 benchmark/benchmark_runner.py --compare-levels -n 100 -c 10

测试脚本在 benchmark/ 目录下,支持对比 Docker、Pyodide、Claude SRT。如果你发现测试方法有问题或者结果与你的环境差异较大,非常欢迎提 Issue 告诉我们。


写在最后

ClawHavoc 给整个 AI Agent 生态敲了一个警钟:当用户执行的代码来自不可信的第三方,传统的应用部署隔离方案可能不够用。这不是哪个方案的问题,而是威胁模型变了,安全策略需要跟着变

这篇文章的目的不是说"SkillLite 最好"——每个方案都有自己的设计初衷和适用场景。我们想分享的是在 ClawHavoc 之后,我们重新审视沙箱安全的思考过程和工程实践。全链路防御只是一种尝试,肯定还有很多不足和可以改进的地方。

如果你也在做 AI Agent 安全相关的工作,很希望能交流一下思路。ClawHavoc 不会是最后一次供应链攻击,行业需要一起把这个问题想清楚。

SkillLite 项目地址:https://github.com/EXboys/skilllite

关于 ClawHavoc 供应链攻击的详细分析,参见我们的另一篇文章:《AI Agent Skills 供应链攻击启示:从 OpenClaw ClawHavoc 看纵深防御》

欢迎 Star、提 Issue、或者直接在评论区聊。感谢阅读!

Logo

有“AI”的1024 = 2048,欢迎大家加入2048 AI社区

更多推荐