
你在用 Claude Code 或 Cursor 写代码顺手装了一个看起来很实用的 Skill。它的 SKILL.md 写得规规矩矩没有可疑命令。配套的脚本你也扫了一遍是正常的工具代码。两边都通过了你的检查于是你放行了。问题是它确实是恶意的。恶意逻辑既不在那段 markdown 里也不在那段脚本里——它藏在两者的配合关系里。markdown 负责诱导 Agent 准备好某个中间文件脚本再去消费它完成最后一步。你把它们拆开看每一半都人畜无害。这不是假设。一篇刚公开的学术论文第一次把这件事系统地摆上了台面。学术界第一次给恶意 Skill建了把尺子这篇论文叫《MalSkillBench》由南洋理工、四川大学、南开大学等机构联合发布。研究团队把恶意 Skill 拆成三个正交维度——恶意逻辑从哪进来、最终想干什么、payload 怎么嵌进去——归纳出 3 类攻击向量、15 类恶意行为、108 个有效攻击单元最后构建出一个含 3,944 个恶意样本、4,000 个良性样本的数据集。最值得注意的是它定义的三类攻击向量里的第三类。第一类是 代码注入CI恶意逻辑直接写在脚本或 markdown 的代码块里最接近传统恶意包凭证窃取、远程执行、反弹 Shell 都在这一类。第二类是 提示注入PI恶意逻辑藏在 SKILL.md 的自然语言说明里不一定带代码而是让 Agent 自己去执行危险动作甚至改掉 Agent 的身份和安全边界。第三类是 混合攻击MIXED把攻击链拆成两段markdown 负责诱导 Agent 生成或下载某个中间对象脚本再消费这个对象完成攻击。论文说得很直白——这种攻击只有在 Agent 同时遵循 markdown 指令、又执行了协调脚本时才会显现。换句话说它的恶意性不在任何一个文件里而在文件之间的关系里。为什么你现有的检查方式正好被它绕开回想一下你怎么审一个第三方包、扩展、Skill扫代码特征比对已知恶意模式看有没有硬编码凭据、可疑域名、危险系统调用。背后是 SAST、SCA、病毒库匹配——全都是静态分析。静态分析有个隐含前提恶意是能在某段代码里被单独揪出来的特征。传统恶意包时代这个前提成立。MIXED 攻击专门打掉了它。恶意拆成两个本身合法的部分扫描器无论扫哪一半都报不出问题。你不是没扫是扫了也看不见。这就是论文反复强调“runtime-verified”运行时验证的原因——只有让 Skill 在 Agent 环境里真的跑一遍看它实际触发了什么行为才能判定是不是恶意。看静态文件得不到答案。而这恰恰是大多数企业当下的盲区开发者每天在 AI 编程工具里随手拉取 Skill但准入这道关要么没有要么还停在“扫一遍代码”的旧逻辑上。拦截要发生在进门那一刻不是装完之后再扫就算你有能力识别恶意 Skill识别的时机也很关键。私有制品仓库、定期 SCA 扫描确实能发现问题但发现得太晚。等下一轮扫描跑起来恶意包早就落地到开发者工位、进了 CI/CD 流水线。情报是有的管控没跟上中间这段时间就是敞开的。业界正在采用的另一种思路是把防护点直接挪到供应链入口每个被拉取的开源组件、第三方依赖、AI 工具包在抵达开发环境之前先过一道情报核验。命中已知恶意当场拦下白名单放行未知样本实时查询——恶意代码进门那一刻就被卡住而不是进门之后再去翻它干了什么。塞讯软件供应链防投毒智能网关CyriGate就是这个思路的落地作为制品仓库代理部署在供应链入口把开发者工位、CI/CD 流水线以及 Claude Code、Cursor 这类 AI 编程工具都设成卡点威胁情报库覆盖传统软件包与 AI Skills 全品类。但要说清边界网关拦的是进门。像 MIXED 这种靠运行时行为才暴露的攻击准入核验之外还得在真实环境里把攻击剧本跑一遍、验证防线挡不挡得住——这是供应链情报到执行验证之间该闭合的另一环。第一步是别让恶意 Skill 在你毫无察觉时就进了开发者的机器。回到最开始那个场景你扫了 markdown扫了脚本两边都干净于是放行。这套动作在三年前没问题。但当攻击者学会把恶意拆进文件之间的关系里“分别检查每个文件”这件事本身就成了被利用的漏洞。值得问自己一句你现在审第三方 Skill 和扩展的方式是为哪个时代设计的是不是上个世纪的你所在的团队AI 编程工具的包准入这道关现在是怎么把的留言聊聊。