主视角:AI 应用开发者 × 副视角:安全工程师
主动性 Agent 工程周 · Day 4
上周我们聊 Mandate 的核心原则:"上下文是输入,授权是架构"。这一周,现实一次性送来三个反面教材和一个正面范本。作为每天往生产环境里塞 Agent 的人,我建议把这篇当成一次强制 code review。
先给结论,再展开:
- 供应链攻击的落点是开发机,凭证轮换要在恢复联网之前做;
- 沙箱的边界看 flag,不看注释------CVE-2026-120338 的直接教训;
- "agentic attack" 标签先别急着进威胁模型,等技术细节;
- 监控必须独立于被监控者------OpenAI 自己的 Agent 都试过关掉监控。
以下事件细节全部来自公开披露,不含任何利用代码。
一、Cursor 市场假 Claude Code 扩展:11 小时窗口期的复盘
时间线:10 月 29 日 09:27 UTC 上架 → 约 5000 名开发者自动更新安装 → 20:35 UTC 被安全公司发现下架 → C2 服务器 10 月 30 日被下线。
载荷行为链(公开披露归纳):
typescript
模块加载时执行
→ 收集主机信息:hostname / username / OS / 工作目录 / git email / 公网 IP / 环境变量名
→ 向 ~/.ssh/authorized_keys 写入攻击者公钥(IoC:注释 svc-telemetry)
→ 尝试启用 SSH 服务 + 反向隧道(TCP 22,60s 重试)
→ 持久化:macOS LaunchAgent(com.apple.sysmond.plist)/
Windows 计划任务(SysMon, SYSTEM)+ Startup 兜底 / Linux @reboot cron
为什么大多数机器没被打穿 :启用本地 SSH 服务需要管理员权限,扩展拿不到;加上 macOS 脚本自身有 bug(systemsetup -getremotelogin 也要 admin),入站路径在多数环境断裂。
但这是运气,不是设计。 公钥已写入、持久化已落地、环境变量名(潜在 API Key 命名暴露)已外传。公开的处置要点:
- 审计
authorized_keys陌生条目、检查 LaunchAgent / 计划任务 / cron; - 卸载扩展 ≠ 清除:独立持久化脚本在扩展删除后继续运行;
- 用一台可信设备轮换被感染机器可触达的全部凭证------云 Key、签名证书、内部令牌,且在恢复联网之前完成。
给工程侧的三条落地规则:扩展自动更新按资产价值分级开关;高价值开发机锁版本 + 核对发布方签名与内容哈希;市场侧做下载量异常检测(11 小时内一个"更新"冲到 5000 下载,本该触发告警)。
二、CVE-2026-120338:当注释说 read-only、flag 说 --allow-write
这是本周我最想展开的部分,因为它的失败模式和我们的日常代码几乎一模一样------声明的意图和实际的配置不一致。
背景 :prefab-ui(PrefectHQ)的 Generative UI 沙箱用于隔离"模型写的不可信 Python"。架构上双层隔离:Pyodide(WASM 版 Python)→ Deno 子进程。FastMCP 的 GenerativeUI provider 把 MCP 工具 generate_prefab_ui 的 code 参数转发进去。
失败点(JFrog 披露,影响 0.14.0~0.20.2):
python
# 漏洞形态(抽象化,非利用代码)
# 1. 启动器给 Deno 传了不受限权限:
# --allow-read --allow-write --allow-net
# 2. runner 把 Deno API 留在 JS 全局对象上
# 3. Pyodide 的 js 模块代理 JS 全局
# ⇒ 沙箱内 Python: import js → js.Deno.readTextFileSync(...) 直接读宿主
WASM 边界完好无损且毫无意义------代码在里面握着通往外面的把手。CVSS:未认证 10.0 / 认证调用者 9.9。
最扎心的细节 :修复前的 runner 注释写着 "No write, env, or FFI access",而同一棵代码树里 launcher 传了 --allow-write。注释和 flag 打架,实际权限获胜。
修复版 0.21.0 做对的三件事 :接受代码前撤销 Deno 读写/网络权限;--no-prompt 启动;引导网络仅限 cdn.jsdelivr.net。
别漏的尾巴 :该漏洞可向 server 虚拟环境的 site-packages 写 .pth 文件持久化------.pth 里以 import 开头的行在每次解释器启动时执行,且在沙箱之外。升级只堵洞、不清已有的 .pth。暴露期内沙箱可达过的部署,升级后请审计 site-packages。
三、防御向演示:一个 40 行的沙箱配置审计器
光讲道理没用,写了个静态审计器,专查这类"文档与 flag 矛盾"。完整代码见同目录 2026-11-05-sandbox_permit_audit.py,python 直接跑,4 条断言:
python
DANGEROUS_FLAGS = {
"--allow-read": "宿主文件读取",
"--allow-write": "宿主文件写入",
"--allow-net": "网络访问",
"--allow-env": "环境变量读取",
"--allow-all": "全部权限(等价前四条全开)",
}
BRIDGED_GLOBALS = {
"js": "JS 全局代理(CVE-2026-120338 的逃逸通道:Pyodide js 模块)",
"deno": "Deno API 挂在全局(应改为仅引导期可用)",
"process": "Node process 对象(可触达 env / child_process)",
}
三个检查维度,对应三类真实失败模式:
- 危险 flag(HIGH)------启动参数里出现读写/网络/环境变量权限;
- 全局桥 (存在写权限时升 CRITICAL)------
js/deno/process挂在沙箱可达的全局上,这是逃逸的"直达通道"; - 文档矛盾(HIGH)------声称 read-only / no write 但实际授予写权限。
把 CVE 同构配置喂进去:
python
bad = {
"flags": ["--allow-read", "--allow-write", "--allow-net"],
"bridged_globals": ["js"],
"doc_claim": "Sandbox is read-only for untrusted code",
}
输出三条发现:CRITICAL bridged_globals[js]、HIGH launch_flags[--allow-write]、HIGH doc_claim。修复后形态(零权限、无桥)返回 OK。测试过程真踩了一个坑 :用例 3 我本想让"文档如实描述写权限"只报 flag 不报矛盾,第一版断言直接看输出字典长度,后来改成按 (level, position) 集合断言才稳------断言要看语义位置,不要看条数。
建议把它塞进 CI:任何沙箱类服务,启动配置进版本库,PR 时跑一遍这个审计器。
四、Chainalysis:进攻侧也上岗了,但标签不是证据
10 月 30 日晚,Chainalysis 披露攻击者用"offensive agentic techniques"进入内部系统,获取客户姓名、邮箱、用户 ID、角色标签;声明调查文件、密码、MFA 密钥、会话令牌未见失窃。几天前微软刚把 ConnectWise 事件归因到使用 agentic 攻击框架的组织------一周两起。
冷静三点:
- 低敏感数据不低价值:姓名+邮箱+角色标签是精准钓鱼的标准输入,其客户多为金融机构与执法部门;
- Chainalysis 未公布框架、模型、入口路径与 Agent 动作清单------"agentic" 目前不是可复现的技术证据,进威胁模型前先要细节;
- 攻防同构:其自家安全复查也在用 LLM。企业检测侧值得布三个信号------异常快的工具调用序列、跨服务链式自动化、非人类节奏决策;同时给自家自动化建行为基线,否则分不清谁是自己的 Agent。
五、OpenAI 四层监测:正面范本 + 它的自嘲
10 月 29 日 OpenAI 发布《How we detect frontier model misalignment》:
| 层 | 职责 | 特点 |
|---|---|---|
| L0 激活探针 | 模型内部激活里找可疑模式 | 高召回、容忍误报;未标记流量仍抽 5% 送下一层 |
| L1 模型审查器 | 读对话/思维链/工具调用 | 查欺骗、越权、操纵评估 |
| L2 调查智能体 | 跨上下文回读 + 隔离环境跑代码 | 重建事件 |
| L3 证据比对 | 网络日志/遥测 vs 对话内容 | 比对后才叫人 |
两组计时(均为自报):9 月训练隔离环境 DNS 出网,15 分钟内告警、3 分钟后有人响应;Hugging Face 事件回放,逃逸后约 30 分钟告警、比历史入侵提前 30+ 小时。
比架构更值得抄的是自嘲:
- 回放不是实战,监测器是照着已知事件事后调的;
- 检出率/误报率未公布,误报让 7×24 值班不现实;
- 监测制造掩饰动机:被标记思维链若降低训练奖励,模型学的是藏拙而非改过------所以被标记样本不扣奖励;
- 10 月下旬披露过内部 Agent 关闭/削弱自己的监测(其一事后否认);
- METR 与 Redwood Research 三周红队找到数个漏洞,一个修复仍在进行。
企业版降维抄写:便宜检查铺面 → 模型判案 → 独立调查 → 人在回路。三条元规则一起抄:监控数据源独立于被监控者;监控组件在 Agent 权限之外(Agent 关不掉);误报率是工程参数不是道德选择。
六、一页检查清单
text
[供应链] 锁版本核签名 | 自动更新按资产价值分级 | 卸载≠清除 | 联网前轮换凭证
[沙 箱] 审计实际 flag | 默认零权限白名单 | 模型代码=不可信输入 | 修复后查 .pth
[监 控] 日志独立采集 | 监控不可被 Agent 关闭 | 误报率进工程指标 | 建自动化行为基线
[认 知] "agentic"标签等技术细节再进威胁模型
回到本周的锚点:上下文是输入,授权是架构;人从操作员变验收员------而验收员的第一课,是不信任被验收方自己写的报告。