Agent Skill 同时是提示词和软件依赖:SKILL.md 告诉模型应该相信什么、调用什么,脚本和工具配置则把这些指令变成文件、网络和凭据访问。
这形成了传统安全工具没有覆盖好的混合攻击面。软件供应链扫描器擅长找危险代码,却不理解自然语言为什么要求执行它;提示注入检测器能看到操纵指令,却通常不跟踪脚本最后做了什么。
MalSkillBench 试图用运行时证据建立统一评测,而不是只靠文件标签判断一个 Skill 是否恶意。
#为什么“看起来恶意”不是可靠标签
公开市场中的恶意样本数量有限,而且高度集中在少数攻击活动。用这些样本测试扫描器,可能得到很高分,却只证明工具识别了某个反复出现的模板。
研究团队收集到的真实恶意样本中,绝大多数集中在依赖冒充等少数模式。提示注入、Agent 控制面劫持和指令与代码协同攻击反而很少。如果把野外样本直接当完整世界,评测排名会严重偏向擅长识别主流模板的工具。
另一方面,合成恶意 Skill 也不能只写一段看似危险的内容。Agent 可能不加载、模型可能拒绝执行、脚本可能因为环境错误根本无法触发。没有运行时证据,标签只是作者声称它会攻击。
#生成、执行、验证的闭环
MalSkillBench 建立了三维分类:攻击载体、恶意行为和插入策略,共 108 个组合单元。载体包括代码注入、提示注入以及两者混合;行为覆盖数据泄露、凭据窃取、远程执行、持久化、目标劫持和安全绕过等类别。
生成 Agent 根据真实恶意软件与提示注入知识生成候选 Skill。每个候选都由真实 Coding Agent 在 Docker 沙箱中加载运行,并通过系统调用和文件事件监控观察行为。只有恶意行为确实触发、且证据与目标标签一致的样本才进入数据集;失败样本携带验证反馈返回生成阶段继续修正。
MalSkillBench 从攻击知识库生成候选 Skill,在沙箱中收集执行轨迹并验证行为证据
最终基准包含 3,944 个恶意 Skill 和 4,000 个匹配的良性 Skill。恶意样本中,3,214 个来自闭环生成与验证,703 个来自真实公开生态,另有少量样本用于工具兼容性校验。
#不同攻击并不一样容易实现
代码注入候选的运行时验证成功率达到 94.5%,混合型为 91.9%,纯提示注入只有 75.8%。覆盖指令重写、目标劫持等行为的样本更难稳定触发。
这不是单纯的数据构造问题。越依赖 Agent 解释和服从自然语言,行为越容易受模型、Harness、上下文和安全策略影响。同一个 Skill 在不同 Agent 上可能表现不同,因此安全评测也不能脱离具体运行栈。
研究还发现,最难稳定生成的指令级攻击,往往也是现有工具最难检测的部分。
#高召回可能只是到处报警
论文在统一输入和指标下测试了 12 种检测工具。最强的 Skill 专项检测器在代码注入上可以达到 98.4% 召回,但面对提示注入和 Agent 控制面攻击时明显下降。只用野外样本评分,某些工具的召回排名最多会波动 66 个百分点。
不同扫描器在恶意行为和插入策略上的召回差异,暴露各自的结构性盲区
把传统供应链扫描器迁移过来,会出现两个极端:部分工具误报很少,却漏掉大多数恶意 Skill;另一些工具接近全量召回,却把 4,000 个良性 Skill 中的三千多个也标成恶意。
提示注入防御同样如此。有的工具几乎捕获所有恶意样本,却也几乎把全部良性样本判错。简单把两类工具做 OR 组合会继承高误报,做 AND 组合又会让召回崩溃。
供应链扫描器与提示注入防御进行 OR/AND 组合后,召回和误报仍无法同时成立
根本原因是恶意性往往不是局部特征。安装依赖、运行 Shell、读取 token 都可能是合法 Skill 的正常行为。真正需要判断的是:这些权限和动作是否为 Skill 宣称的任务所必需,指令与代码组合后是否越过了合理边界。
#静态扫描必须与运行约束配合
MalSkillBench 说明,可靠防御至少需要同时检查任务意图、自然语言指令、脚本实现和实际运行行为。安装前的包级静态检查仍然必要,但不能作为唯一防线。
部署时还需要限制文件系统、网络、凭据和命令权限,把未知 Skill 放进隔离环境,记录系统调用与外部连接,并对敏感动作保留确认。Skill 版本更新后应重新检查,因为一段看似普通的指令变化也可能改变未来 Agent 行为。
这项研究仍有边界:大量样本是基于攻击知识生成的,验证过程部分依赖 LLM Judge,真实样本又集中在少数活动。它不能代表所有未来攻击。但运行时验证至少把问题从“这段内容像不像恶意”推进到了“真实 Agent 是否会执行可观察的恶意行为”,为后续安全工具提供了更可信的共同尺子。