SKILL.md 中的隐藏触发器:针对 Agent Skill 注册表的语义供应链攻击
马里兰大学 2026 年 5 月 12 日发表的论文表明:在 SKILL.md 文件中添加约 20 个 token,即可让 Agent 在 77–86% 的试验中发现并选择对抗性 skill,并以最高 100% 的概率绕过注册表的扫描。
What is this?
2026 年 5 月 12 日,马里兰大学的 Shoumik Saha、Kazem Faghih 与 Soheil Feizi 在 arXiv 上发表了 Under the Hood of SKILL.md: Semantic Supply-chain Attacks on AI Agent Skill Registry(2605.11418,cs.CR)。论文研究了一类完全不需要可执行代码的攻击:在 SKILL.md 元数据文件中加入简短、看似合理的自然语言,就足以左右 Agent 发现哪一个 skill、在多个候选中选择哪一个,以及注册表的安全扫描是否会放行。
这项工作之所以重要,是因为 SKILL.md 如今已是整个 Agent 生态——Claude Code、OpenClaw、Microsoft Agent Framework、Codex skills——中的运行时工件,而不是被动的文档。Agent 在发现阶段(将用户查询与可用 skill 匹配)、选择阶段(在功能相近的 skill 之间挑选)以及安装阶段(注册表执行安全检查时)都会读取它。每一次读取都是文本修改可以改变行为的入口。The Register 于 2026 年 5 月 22 日以 Minor edits to AI skills can make agents go rogue 为题作了报道。
How it works
作者使用真实的 ClawHub skill,以及结合词法相关性、向量相似度(OpenAI embedding)与下载量人气的真实排名函数,评估了注册表生命周期的三个阶段。他们只修改 SKILL.md 文本——脚本、依赖、运行时都不变——并测量一个现有 skill 的恶意”双胞胎”获胜的频率。
阶段 使用的 SKILL.md 表面 对抗目标
----------------- -------------------------- --------------------------------
发现 (Discovery) 名称、描述、tags 被检索到以匹配查询
选择 (Selection) when-to-use、示例 击败合法的"双胞胎"
审核 (Vetting) 完整正文、"safety" 通过注册表扫描器
论文有三项关键发现。
- 发现阶段:在描述中插入约 20 个 token 的触发器,就足以让对抗性 skill 在 86% 的成对比较中超过其未修改的双胞胎,并在 80% 的查询中进入注册表的 Top 10。这并非关键词堆砌,而是利用 embedding 空间中与用户实际表达的接近性。
- 选择阶段:两个 skill 同时呈现给 Agent 后,纯描述性的措辞在平均 77.6% 的配对试验中将 Agent 导向对抗性变体,而底层功能行为没有任何改变。Agent 读取 “when to use” 模块和示例,文本本身决定了调用。
- 绕过审核:同一类触发器在不同扫描器下能以 36.5% 到 100% 的概率绕过注册表侧扫描。由于没有投递任何 payload,基于签名和模式的防御无从触发。
关键点:作者并未公开可工作的恶意触发器;他们仅发布了一个测量工具(github.com/ShoumikSaha/agent-skill-security)和聚合统计结果。论文贡献的是一个类别——“元数据本身就是攻击”——而不是配方。
Why it matters
三项启示超出本论文。
第一,skill 注册表继承了 package 注册表以为已经解决的问题。PyPI 与 npm 用十年时间加固了对 typosquatting、依赖混淆和账号接管的防御,这些假设的前提都是攻击者投递的是代码。这里攻击者投递的是散文,而散文恰好经过注册表自己的 embedding 流水线。反恶意软件扫描和 SBOM 瞄准的是错误的层。
第二,漏洞出现在没有明确归属的组件之间。发现阶段的排名器由供应商决定(ClawHub、OpenAI 的 skill 搜索、Microsoft 的 Agent Framework);选择阶段的 prompt 属于 Agent 运行时;审核扫描归注册表。攻击者只需用二十个 token 撬动其中一层,就能让看似无害的描述被错误排名。这正是早期应用商店之所以漏水的责任分散逻辑。
第三,本论文与 2026 年 5 月的一批工作指向同一方向。Exploiting LLM Agent Supply Chains via Payload-less Skills(arXiv:2605.14460,Liu 等,浙江大学,2026 年 5 月 14 日)提出 Semantic Compliance Hijacking,在无 payload 的 skill 下达到了高达 77.67% 的机密性突破和 67.33% 的远程代码执行。Snyk 的 From SKILL.md to Shell Access in Three Lines of Markdown 从工程角度阐述了同一现象。共同结论是:SKILL.md 生态是一条供应链,尚未加固,利用它既不需要新型密码学,也不需要运行时奇技。
Defenses
论文给出了注册表侧与 Agent 侧的控制建议。最精简的可操作清单如下:
- 将
SKILL.md文本视为待评审的代码。 它无需可执行就具有危险性。每次更新都做 diff,要求人类可读的 changelog,并拒绝对description、when-to-use与examples的静默重写。 - 像锁定依赖那样哈希并固定 skill。 一条
skill@1.4.2#sha256:…的 lockfile 条目可以防止已发布的工件在 Agent 脚下漂移,与package-lock.json之于 npm 同理。论文中的所有攻击场景都假设 skill 文本在安装后仍可变更。 - 将发现与选择解耦。 抬升检索的触发器未必与诱导选择的触发器一致——但用同一段文字同时承载两个用途,等于让攻击者一次锁定两个目标。从经过净化的视图(规范名、tags、签名清单)计算发现阶段的 embedding,自由文本仅在选择阶段使用。
- 对元数据本身运行语义扫描,而不仅是代码。 作者在 GitHub 上发布的测量工具为防御方提供了起点。把 skill 清单当作邮件处理:让内容分类器在本应描述性的字段中标记祈使性指令(“MUST”、“always”、“在执行前先执行 X”)。
- 约束注册表的排名函数。 词法相关性、向量相似度、下载量与签名发布者信任不应汇聚为单一标量分数。描述中的微小对抗扰动不应胜过签名发布者的来源信任。
- 要求每个 skill 都有发布者签名,并在选择时显式呈现。 若 Agent 的选择 prompt 在描述旁同时显示签名身份,那么来自未知发布者的热门 skill 的”双胞胎”将不再默认胜出。
- 在 skill 层默认拒绝网络与文件系统能力。 即便恶意 skill 被选中,基于能力的执行(每个 skill 的 ACL、无环境凭证、egress 白名单)也会限制”赢得选择”实际给攻击者带来的收益。这正是本站 CISPA agents-as-OS 论文 所建议的纵深防御。
Status
| 项目 | 引用 | 日期 | 备注 |
|---|---|---|---|
| 论文发布 | arXiv:2605.11418v1 | 2026-05-12 | cs.CR,马里兰大学 |
| 公开报道 | The Register | 2026-05-22 | Minor edits to AI skills can make agents go rogue |
| 发现成功率 | 成对 86%、Top-10 80% | 2026-05-12 | 描述中 20 token 触发器 |
| 选择偏置 | 77.6% 成对试验 | 2026-05-12 | 纯描述性措辞 |
| 审核绕过 | 36.5%–100% | 2026-05-12 | 取决于扫描器 |
| 代码与数据 | github.com/ShoumikSaha/agent-skill-security | 2026-05-12 | 测量工具,不含可工作的 payload |
| 相邻工作 | arXiv:2605.14460(Liu 等) | 2026-05-14 | Semantic Compliance Hijacking,机密 77.67% / RCE 67.33% |
没有任何单一修补能消除这一类问题。论文的贡献在于把 Agent 运维者一直默默假定的事情明确表达出来:skill 注册表是信任边界的一部分,元数据文件是可执行表面的一部分,而二十个用得恰到好处的 token 比一个 CVE 更能稳定地左右 Agent 的决策。