
过去讨论 Agent 安全,我们经常把重点放在运行时:Agent 会不会调用危险工具,会不会读到恶意网页,会不会把敏感信息发出去,会不会被提示注入带偏。
但这篇论文把问题往前推了一步。
风险不一定等到 Agent 执行工具时才出现。一个第三方 Skill 还没有真正运行,只是在技能市场里被搜索、被排序、被 Agent 选择、被注册表审核的时候,攻击可能已经开始了。
论文《Under the Hood of SKILL.md: Semantic Supply-chain Attacks on AI Agent Skill Registry》研究的是一个很具体但很关键的问题:SKILL.md 到底是不是一份普通说明文档?

https://arxiv.org/pdf/2605.11418
作者的回答很明确:不是。
SKILL.md 是 Agent Skill 的语义控制面,它会影响一个 Skill 能不能被发现、能不能被选中、能不能通过审核,最终影响 Agent 会信任并加载哪些第三方能力。
论文基于真实 ClawHub Skill 做实验,围绕 Discovery、Selection、Governance 三个阶段验证了 SKILL.md-only 攻击的有效性。
这也是 Agent 生态走向插件化、市场化之后绕不开的新问题:当 Agent 的能力像应用商店一样分发,Agent 安全就不再只是模型安全、提示词安全、工具调用安全,而会变成一种新的供应链安全。
SKILL.md 为什么会变成攻击面?

Agent Skill 可以简单理解为 Agent 的“能力插件包”。它可能包含任务说明、脚本、参考资料、工作流程、资源文件等,而 SKILL.md 通常是其中最重要的入口文件。
它一方面像传统软件里的 manifest,告诉注册表和 Agent:这个技能叫什么、适合什么任务、什么时候应该被使用。另一方面,它又像一段可被 Agent 读取和遵循的提示词,告诉 Agent 在加载这个技能之后应该如何执行任务。论文明确指出,SKILL.md 的 name、description、Markdown 正文会同时影响技能路由和 Agent 行为。
这就和传统软件供应链不一样了。
传统软件供应链里,我们主要担心恶意代码、恶意依赖、安装脚本、二进制文件、后门包。但在 Agent Skill 生态里,自然语言也进入了供应链。一个 Skill 的描述怎么写,流程怎么安排,完成标准怎么定义,安全声明怎么包装,都可能改变 Agent 对它的判断。
所以这篇论文最值得关注的地方,不是证明“提示注入又多了一种形式”,而是提出了一个更大的判断:Agent Skill 市场里的自然语言元数据,本身就具有供应链安全属性。
第一类攻击:让恶意 Skill 更容易被搜到
Agent 要使用 Skill,第一步通常是发现。用户提出一个任务,注册表根据查询词搜索相关 Skill,再把结果返回给用户或 Agent。
很多注册表会使用向量检索,也就是把用户查询和 SKILL.md 编码成 embedding,再根据语义相似度排序。论文发现,攻击者只需要在 SKILL.md 里追加很短的一段文本,就可以明显提高目标 Skill 在特定查询下的检索分数。
这里的关键不是攻击者改了代码,也不是 Skill 真的变强了,而是它在语义空间里变得“更像用户想找的东西”。
论文实验中,作者使用 beam search 和梯度优化等方式生成短触发文本。触发文本长度约 20 个 token,只占平均 SKILL.md 长度大约 1%,但已经足以改变检索结果。针对 OpenAI/text-embedding-3-small 的黑盒攻击取得了 86.14% 的 pairwise win rate,平均检索分数提升 16.40%。

在 Top-k 排名里,攻击后的 Skill 进入 Top-3、Top-5、Top-10 的比例分别达到 56%、65%、80%。

更值得注意的是,论文还模拟了更接近真实注册表的排序机制。ClawHub 风格的排序不只看向量相关性,还会结合关键词相关性和下载量。即便加入下载量这种“流行度信号”,攻击修改后的 Skill 仍然能在平均日场景下超过基线 74.14%;在新 Skill 零下载的冷启动场景下,刚发布时胜率达到 94%,一小时后仍有 40%。
这说明问题不只是“embedding 模型有漏洞”。真正的问题是:一旦 Agent 技能市场依赖语义检索,搜索排序本身就变成了安全入口。
以前我们熟悉 SEO 投毒,攻击者通过关键词堆叠、标题包装、链接操纵,让恶意网页排到搜索结果前面。Agent Skill 市场也可能出现类似问题,只不过这里被操纵的不再是搜索引擎,而是 Agent 的能力发现机制。
第二类攻击:让 Agent 更愿意选择攻击者版本
搜索出来只是第一步。真正危险的是,Agent 还要在多个候选 Skill 之间做选择。
论文设计了一个很有意思的实验:给 Agent 两个功能等价的 Skill,一个是原始版本,一个是攻击者版本。攻击者版本不改代码、不改功能,只改 description 字段,比如让描述看起来更专业、更权威、更安全、更值得信任。
按理说,两个 Skill 功能相同,Agent 不应该有明显偏好。但实验结果显示,Agent 很容易被描述文本影响。
论文构造了四类描述操纵方式:夸大能力、使用更强指令语气、强调可信安全、强调活跃维护。实验覆盖 100 个 Skill、4 类变体、每个 Skill 5 个任务提示,并在 GPT-4.1-mini、GPT-5、Gemma-4-31B、Qwen3-235B-A22B-Instruct 上进行测试。最终,攻击者版本平均被选择的比例达到 77.6%,明显高于随机选择的 50%。

这个结果很有现实意义。
今天很多 Agent 系统在选择工具、插件、Skill 时,会读取工具说明、功能描述、使用场景,然后让模型自己判断“哪个更适合当前任务”。这套机制本质上依赖模型对自然语言描述的理解。
但问题在于,模型并不能天然区分“真实能力”与“自我包装”。
一个 Skill 写着“官方推荐”“最安全”“持续维护”“企业级可靠”,如果这些声明没有外部证据支撑,Agent 仍然可能把它当作可靠信号。论文里所谓的 selection manipulation,本质上就是一种面向 Agent 的语义社会工程。
人会被营销话术影响,Agent 也会。
而且 Agent 的问题可能更隐蔽。人看到一个插件自称“最安全”,可能会怀疑它是不是广告;但 Agent 在工具选择阶段,往往会把这些描述当成任务相关证据来处理。于是,一段看似正常的产品描述,就可能成为攻击者争夺 Agent 决策权的入口。
第三类攻击:让恶意意图逃过注册表审核
如果说前两类攻击解决的是“如何被看见”和“如何被选中”,第三类攻击解决的就是“如何通过审核”。
论文模拟了一个 ClawHub 风格的三阶段治理流程:
第一层是静态扫描,检查高风险模式,比如权限执行、动态代码执行、凭证访问、可疑 URL、提示注入短语等;
第二层是 LLM 审核器,从语义层面判断 Skill 的目的、指令范围、安装行为、凭证使用是否合理;
第三层是 VirusTotal 扫描技能目录,检查外部恶意软件信号。最终判定分为 clean、suspicious、malicious。
作者先从 100 个真实 ClawHub Skill 中筛出 47 个完全 clean 的英文 Skill,再为每个 Skill 生成两条与技能用途相关的恶意指令,形成 94 个恶意变体。这样做的目的,是排除原始 Skill 本身就可疑的干扰,只观察 SKILL.md 修改带来的影响。
直接插入恶意指令时,审核系统表现还不错:没有一个变体被判定为 clean,68.2% 被判定为 malicious。但如果注册表只阻断 malicious,而允许 suspicious 带警告展示,那么仍然有大约 32% 的直接恶意变体不会被真正阻断。
更严重的是,当攻击者不再直白地写恶意意图,而是用更隐蔽的方式表达,绕过率明显上升。
论文测试了几种方式:把危险语义改写成更像正常自动化流程的语言;把恶意行为拆散,放进“完成标准”或 checklist 里;利用 LLM 审核器只读取前一部分内容的截断机制,把危险指令放到审核上下文之外。结果显示,语义改写后 73.9% 的变体避开 malicious 判定;Definition-of-Done 形式下 66.3% 避开阻断;上下文窗口溢出最强,87.1% 被判为 clean,没有一个被判为 malicious。

这部分对工程实践的启发非常直接。
很多安全审核系统容易做成“关键词扫描 + LLM 简单判别 + 文件扫描”的组合。但 Agent Skill 的风险不一定以明显恶意词出现。它可能藏在流程步骤里,藏在完成标准里,藏在异常处理里,藏在一段“看似合理”的自动化操作里。
尤其是上下文窗口问题,非常现实。
为了控制成本和延迟,很多审核系统不会把完整文件都丢给 LLM,而是截取前 N 个字符,或者只抽取部分字段进行审核。如果 SKILL.md 很长,攻击者完全可能把关键指令放在后面,让审核器看不到,但 Agent 在真正加载 Skill 时却能看到。
这说明,Agent Skill 审核不能只问“有没有明显恶意内容”,还要问“审核系统看到的内容,和 Agent 最终执行时看到的内容是不是一致”。
语义供应链安全
这篇论文最有价值的地方,不是提出了某个特别复杂的攻击算法,而是把 Agent Skill 的安全边界重新画了一遍。
过去我们看 Agent 安全,通常会从三个层面出发。
第一层是模型层,看模型是否容易被提示注入、越狱、诱导违规输出。
第二层是工具层,看 Agent 调用工具时有没有权限控制、参数校验、敏感操作确认。
第三层是运行时层,看 Agent 的中间状态、记忆、上下文、工具返回结果会不会被污染。
这篇论文补上了一个更前置的层面:注册表生命周期。
一个 Skill 进入 Agent 系统之前,需要经过提交、审核、索引、搜索、排序、展示、选择、加载,每个环节都可能被 SKILL.md 的自然语言内容影响。攻击者不一定要马上让 Agent 执行恶意命令,他可以先让自己的 Skill 更容易被搜到,更容易被选中,更容易看起来安全,更容易通过审核。
这就是所谓语义供应链攻击。
它不是传统意义上的代码投毒,而是能力分发链路中的语义投毒。攻击载体不是恶意二进制,而是一段说明、一段描述、一段任务流程、一段完成标准。
Agent 时代的一个麻烦之处就在这里:自然语言既是用户界面,也是程序接口;既是说明文档,也是行为指令;既能表达能力,也能操纵能力选择。
对 Agent 平台的防护启发
这篇论文对 OpenClaw、Claude Code Skill、企业 Agent 平台、内部工具市场都有直接启发。
首先,注册表不能把 SKILL.md 当成普通文档处理。它应该被视为安全敏感输入,进入和代码、依赖、权限清单类似的安全治理流程。审核时不应只扫关键词,也不应只让 LLM 看开头片段,而要做全文分块审核,重点关注 workflow、completion checklist、credential handling、network behavior、error handling 这类更容易承载隐蔽指令的部分。
其次,搜索排序不能只依赖语义相似度。Skill 排名应该结合发布者可信度、签名、历史版本变化、下载异常、权限请求、审核结果、运行时行为测试等信号。对于新发布 Skill,尤其要警惕冷启动阶段通过语义触发快速获得曝光。
再次,Agent 在选择 Skill 时,不能把 Skill 自己写的“安全、可靠、官方、最佳、持续维护”当成事实。更合理的做法,是把这类自我声明降权,只允许使用注册表验证过的外部证据,比如认证发布者、签名证明、安全扫描结果、权限范围、历史调用记录和社区审计结果。
最后,运行时仍然要做最小权限控制。即使一个 Skill 通过审核,也不应该默认拥有文件系统、网络、shell、凭证、浏览器、代码仓库等高权限。Agent 调用 Skill 时,需要根据任务上下文动态授予权限,并对敏感操作进行审计和确认。
论文最后也提出,未来注册表需要提供更清晰的审计信号,比如为什么一个 Skill 被排序、被选择、被批准;同时结合透明日志、社区报告、签名证明、撤销机制等治理方式。
局限性
这篇论文为了隔离变量,只研究 SKILL.md-only 攻击,没有研究辅助文件、可执行代码、依赖包、运行时行为被同时修改的情况。现实攻击可能更复杂,也可能把语义操纵和代码恶意行为结合起来。作者也承认,实验只覆盖 100 个 ClawHub Skill 和五个类别,治理流程虽然参考 ClawHub,但仍然是本地实现,未来不同注册表、不同审核策略下结果可能变化。
但这并不削弱论文结论。恰恰相反,只改 SKILL.md 就能产生这些影响,已经说明 Agent Skill 生态存在一类非常轻量、非常隐蔽、非常靠前的攻击面。
写在最后
Agent 的能力生态正在变得越来越像应用商店。开发者会发布 Skill,用户会安装 Skill,Agent 会自动搜索和选择 Skill,注册表会负责排序、审核和分发。
这是一种很自然的产品演进。没有 Skill 生态,Agent 很难扩展到复杂任务;但一旦有了 Skill 生态,安全问题也会从单个 Agent 的运行时,扩展到整个能力供应链。
这篇论文真正提醒我们的是:Agent 时代的供应链组件,不再只有代码、依赖和二进制文件,也包括自然语言。
SKILL.md 看起来像说明书,但在 Agent 系统里,它会影响搜索、排序、选择、审核和执行。它不是被动文档,而是操作性文本;不是外围材料,而是控制面的一部分。
当 Agent 开始阅读文档、相信文档、按照文档行动,文档本身就成了安全边界。
声明:本文来自模安局,版权归作者所有。文章内容仅代表作者独立观点,不代表安全内参立场,转载目的在于传递更多信息。如有侵权,请联系 anquanneican@163.com。
