AI代理安全需要组合图,而非仅SBOM
传统软件组合分析(SCA)仅关注包依赖漏洞,但AI代理的风险源于组件组合。OpenACA项目通过构建代理组合图,揭示插件、技能、MCP服务器等组件间的交互,从而识别真正的安全风险。
近年来,随着AI代理的广泛应用,其安全性问题日益凸显。传统软件组合分析(SCA)仅关注包级别依赖中的已知漏洞,但AI代理的真正风险往往来自组件之间的组合方式。以Claude官方插件市场为例,文章深入探讨了为何我们需要从包依赖转向组合图分析。
插件“imessage”是Claude Code中一个可一键安装的插件,允许AI代理读取和发送iMessages。其底层架构包含三个主要部分:一个本地MCP服务器,用于读取用户完整的消息历史(需要完全磁盘访问权限),并通过AppleScript代表用户发送消息;一对技能“configure”和“access”,持有读写及受限的Bash权限,并将访问控制状态写入配置文件;以及91个npm包作为支撑。每个组件单独来看都是安全的:MCP服务器按设计工作,技能行为正常,包也仅是常见的Web服务器依赖。如果对仓库运行SCA扫描,只会得到一份干净的锁文件报告,指示少数几个包如hono和path-to-regexp存在中危漏洞。修补这些包后报告变为绿色,但用户对实际风险几乎一无所知。
因为风险从未存在于任何单个包中,而是存在于组合之中:一个连接了不受信任输入的代理(每个入站文本都会落入它读取的消息存储中),能够读取私人消息历史、代表用户发送消息,并且由可以重写谁被允许控制它的技能所管理。所有这些都在同一个上下文中,由各部分单独审查后组装而成。这并非假设。研究者实际扫描了官方Claude插件市场——62个清单、530个组件:38个插件、27个技能、26个命令、21个代理、16个MCP服务器、8个钩子,以及其下的394个包。扫描结果发现了124个已知漏洞通告。有趣的是,所有这些通告都恰好来自四个插件:discord、telegram、fakechat和imessage,即四个消息通道插件。这些漏洞集中在处理不受信任外部消息并能发送本地文件的插件中。易受攻击的代码和敏感能力位于同一组件,这正是逐包扫描无法表达的相关性,因为它从未知道这些包属于一个读取消息的代理。
SCA只能回答依赖树是否包含已知漏洞版本,但无法告知包在代理中的实际上下文。运行时监控虽然能捕获执行中的不良行为,但不能在安装前揭示组合风险。因此,我们需要第三个视角:代理组合图。代理堆栈并非扁平的依赖列表,而是一个图。插件包含技能、MCP服务器和钩子,这些组件声明能力并引入包。权限和安装路径也参与其中。安全分析需要关注节点间的边,而不仅仅是节点本身。一个扁平的SBOM列出了所有盒子,但无法告诉你红色盒子与不受信任输入源、私人数据读取器和出站接收器位于同一上下文中。图则可以做到这一点。
开源项目OpenACA正致力于构建这一层。目前,OpenACA可以盘点整个代理堆栈,将每个包通告归因于引入它的代理组件(这正是我们得知所有124个通告存在于四个插件中的方法),标记可变动安装和执行技能能力等姿态问题,并以CycloneDX格式输出代理BOM——可导出的组合图。下一步是图导出的暴露分析,即仅因组合而触发的规则,例如“此上下文结合了不受信任输入、私人数据读取和出站接收器;需审查”,并基于是否存在可行的影响路径对发现进行优先级排序。OpenACA目前尚未计算这些暴露路径,但盘点、归因和图是使其成为可能的基础。
作者提供了一个简单的练习:对代理插件仓库运行SCA扫描,然后问自己——能否找出哪个漏洞可通过Claude技能、生命周期钩子或能发送本地文件的MCP服务器被利用?如果不能,说明你看到的只是锁文件,而非代理本身。通过运行uvx --from openaca openaca scan repo --target . --include-posture,可以查看任何包含插件、技能或MCP服务器的仓库的组合情况:安装了哪些组件,它们如何连接,以及哪些通告和姿态发现属于哪个代理组件。
总之,AI代理安全需要组合感知分析,而不仅仅是包扫描。包从来不是单元,代理才是。