Agent 时代的供应链风险,不只在代码里,也在工具、依赖和运行权限里
过去谈软件供应链安全,我们通常会画出这样一条链路:源代码、第三方依赖、构建系统、软件包、部署产物。相应的防御手段也围绕这条链展开:用 SCA 检查依赖版本和已知漏洞,用 SBOM 建立组件清单,用静态分析寻找代码缺陷,再对构建和发布环节进行签名与审计。
但 Agent 正在改变这条链路。
一个现代 Agent 系统不仅包含代码和模型,还可能接入 MCP Server、命令行工具、数据库、浏览器、云平台、GitHub、企业内部 API,以及保存在本地或云端的密钥。它会读取上下文、选择工具、申请权限、执行命令,并将结果发送给模型服务商。
因此,Agent 时代的供应链风险已经不能只问:
这个项目依赖了哪些软件包?
还必须继续问:
这些工具从哪里来?
它们获得了什么权限?
Agent 在什么条件下会调用它们?
调用后可以读取什么数据、执行什么操作,又能把数据发送到哪里?
最近发生的三类事件,恰好展示了这种风险边界的扩张。
Langflow:被攻破的不只是一个 Web 服务
2025 年5月5日,美国网络安全和基础设施安全局将 Langflow 的 CVE-2025-3248 加入已知被利用漏洞目录。该漏洞影响 Langflow 1.3.0 之前的版本,未经身份认证的远程攻击者可以通过 /api/v1/validate/code 接口执行任意代码。
单独看,这似乎只是一个典型的未授权远程代码执行漏洞。但 Langflow 并不是普通的信息展示网站。它是用于构建和运行 AI Agent、工作流及 MCP 服务的平台。其官方文档显示,Langflow 的全局变量可以保存并复用 API Key 等凭据,这些变量存储在内部数据库中;环境变量也可能包含供工作流使用的密钥。
这意味着,Langflow 实例实际上可能同时承载四类重要资产:
第一类是已经编排完成的 flow,它决定模型、工具和数据源之间如何连接;第二类是 API Key、数据库凭据等秘密信息;第三类是 Agent 可以调用的组件和外部服务;第四类是服务器进程自身具备的文件、网络和执行权限。
需要区分的是,远程代码执行漏洞本身并不能证明攻击者已经窃取了所有密钥,也不能证明每个 Langflow 实例都具有同样的权限。但从威胁建模角度看,一旦攻击者能够以 Langflow 进程的身份运行代码,其可能触达的对象就不再局限于一段有缺陷的源代码,而是包括数据库、环境变量、工作流配置、内部网络和外部工具。
所以,评估这类漏洞时,仅给出一个 CVSS 分数是不够的。真正决定影响范围的是:
Langflow 进程以什么身份运行,它连接了哪些工具,保存了哪些凭据,又能访问哪些内部资源?
Agent 平台正在成为新的控制平面。控制平面一旦失守,风险会沿着工具和权限关系向外扩散。
Injective:最便宜的攻击入口,仍然可能是发布链
2026 年7月9日,Socket 披露 @injectivelabs/sdk-ts@1.20.21 被植入恶意逻辑。恶意代码被包装成遥测功能,在应用调用 fromMnemonic、fromHex 等正常的钱包密钥处理函数时,收集助记词和私钥并向外发送。它不是在安装阶段立即执行,而是隐藏在正常业务路径中。
这次事件还有一个重要细节:攻击者不只发布了一个恶意 SDK 版本,还同步发布了17个依赖并锁定该恶意版本的 @injectivelabs 作用域软件包。因此,即使开发者没有直接声明 sdk-ts,也可能通过传递依赖引入恶意代码。
这一攻击路径并不新奇,却仍然有效:
攻击者不需要寻找复杂的业务漏洞,也不需要直接攻破每一个使用 Injective SDK 的项目。只要获得维护者账户、代码仓库或发布凭据的控制权,就能够借助原有的依赖传播关系,把恶意逻辑送进大量下游系统。
更麻烦的是,恶意版本仍然使用官方包名、官方作用域和兼容的 API。软件可能正常安装、正常构建,主要功能也能继续运行。对于普通开发者来说,它看起来更像一次正常的依赖升级,而不是一次入侵。
传统 SCA 可以帮助组织识别自己使用了哪个软件包、哪个版本,以及该版本是否关联已公开的 CVE。但对于刚刚发布、尚未形成漏洞编号和稳定检测特征的恶意版本,仅有依赖清单并不足以回答以下问题:
这个版本是谁发布的,发布身份是否发生变化?
新版本增加了哪些网络行为和秘密数据访问?
某个依赖是否从普通工具库变成了密钥处理路径上的数据出口?
恶意版本通过多少层传递依赖进入了实际运行环境?
因此,Agent 供应链不能只记录“依赖了什么”,还需要记录“依赖在运行时获得了什么能力”。
Claude Code 争议:Coding Agent 已经进入合规与数据边界
Claude Code 更能说明,Agent 风险不只是传统意义上的软件漏洞。
Anthropic 对 Claude Code 的官方定义是:它可以读取代码库、编辑文件、运行命令,并与开发工具集成。换句话说,它不是只负责生成代码文本的聊天窗口,而是运行在开发环境中的执行主体。
2026 年7月,Claude Code 因其用户环境识别机制引发争议。路透社报道称,开发者发现某些版本会检查时区、代理等环境信息,并在发送给服务端的提示中插入标记。Anthropic 员工将其解释为一项用于打击未授权转售和模型蒸馏的实验。阿里巴巴随后禁止员工在工作中使用 Claude Code。
这里不能把“存在后门”直接写成已经确认的事实。公开信息目前支持的事实是:相关环境检测机制确实引发了审查,Anthropic 方面将其解释为反滥用措施,而企业据此作出了内部合规决策。对该机制是否应被定义为“后门”,仍然存在立场和定义上的争议。
但即使不讨论这一争议的政治背景,它仍然揭示了一个基础问题:当 Coding Agent 具有读取仓库和执行命令的能力时,企业需要知道它究竟收集、传输和保存了什么。
Anthropic 的数据使用文档显示,Claude Code 会通过网络发送用户提示和模型输出;商业用户标准的数据保留期为30天,零数据保留需要满足条件并单独启用。客户端还会默认在 ~/.claude/projects/ 下以明文形式保存本地会话记录30天。云端执行模式则会把仓库克隆到由 Anthropic 管理的隔离虚拟机中。
这些设计并不等同于恶意行为,官方也提供了数据保留、组织管理和零数据保留等控制机制。但它说明 Coding Agent 的采购和部署已经不能只比较模型能力,还必须纳入:
数据是否跨境、代码是否离开本地、会话记录保存在哪里、日志由谁访问、第三方模型代理如何处理数据,以及企业能否审计每一次工具调用。
对于普通代码补全工具,这些问题可能只是隐私条款;对于能够执行 Shell、访问仓库和调用企业系统的 Agent,它们已经属于供应链安全和身份权限治理问题。
为什么传统 SCA 和 Semgrep 还不够
这里需要避免一个错误结论:SCA 和 Semgrep 并不是没有价值。
OWASP 将 SCA 描述为组件分析中范围相对有限的软件子集,其核心能力是建立第三方组件清单并识别相关风险。Semgrep 则通过模式匹配、控制流和数据流分析,在源代码中定位安全相关路径。它们仍然是软件安全体系的重要基础。
问题在于,Agent 系统中的风险路径可能跨越多个传统工具分别管理的对象:
npm 包
→ MCP Server
→ 工具定义
→ Agent 的工具选择
→ OAuth Token
→ 云平台权限
→ 文件或数据库读取
→ 外部网络请求
这里有些节点是代码,有些是 JSON、YAML 或工具描述;有些边来自依赖关系,有些来自权限配置,还有一些只有在运行时才会出现。
Semgrep 可以分析某段代码是否调用危险函数,也可以通过自定义规则扫描部分配置文件。SCA 可以发现软件包及其已知漏洞。但二者通常不会天然建立一条完整的跨对象路径:
某个第三方来源提供的工具,在什么 Agent 配置下获得了哪项凭据,并能够通过什么调用路径把哪个资源发送到哪个外部端点?
MCP 规范本身也明确提醒,工具代表潜在的任意代码执行能力,工具描述和注解在来源不可信时也应当被视为不可信输入。
因此,Agent 安全缺少的并不只是更多扫描规则,而是一种能够统一表达代码、工具、来源、权限和运行行为的分析模型。
所以我们想要做一个 AgentSupplyGraph,如下:
AgentSupplyGraph 应该刻画什么
AgentSupplyGraph 的核心不应只是画一张更大的依赖图,而应回答“能力如何沿供应链传播”。
这张图至少需要包含以下对象:
软件包、仓库、镜像和发布者;
Agent、模型、MCP Server 和具体工具;
工具描述、配置文件、Hook 和提示模板;
API Key、OAuth Token、云身份及其他凭据;
文件、数据库、代码仓库和企业内部服务;
Shell、网络、文件读写、部署和管理权限;
最终可能接收数据的外部端点。
它还需要表达不同类型的边:
published_by 由谁发布
depends_on 依赖什么
exposes_tool 暴露哪些工具
configured_by 受什么配置控制
authorized_by 使用什么身份或凭据
reads 可以读取什么
writes 可以修改什么
executes 可以执行什么
invokes 会调用什么
sends_to 可以向哪里发送数据
runs_as 以什么系统身份运行
reachable_from 能从哪个入口到达
在此基础上,分析器才可以搜索这样的风险路径:
不可信来源
→ 可加载组件
→ Agent 可选工具
→ 高权限凭据
→ 敏感资源读取
→ 外部网络端点
Injective 事件可以被描述为:
受影响的发布身份
→ @injectivelabs/sdk-ts@1.20.21
→ fromMnemonic / fromHex
→ 助记词与私钥
→ 伪装成正常遥测的 HTTP 请求
Langflow 风险可以被描述为:
公开接口
→ 任意代码执行
→ Langflow 进程身份
→ 内部数据库或环境变量
→ 已连接工具与网络资源
Claude Code 的合规路径则可能是:
本地仓库或会话上下文
→ Coding Agent 客户端
→ 模型服务或代理提供商
→ 服务端保留与审计边界
需要强调的是,这类图分析首先能证明的是静态存在性和可达性,而不是实际攻击成功。发现一条“凭据可以到达外部端点”的路径,不代表数据已经泄露,也不代表模型必然会选择该工具。
AgentSupplyGraph 更合理的输出应该是:
存在一条具有证据支持的潜在行为路径,需要进一步通过运行日志、沙箱实验或人工审查验证。
这种限定非常重要。否则,工具只是把“可能发生”包装成“已经发生”,最终仍会产生大量无法使用的告警。
从 SBOM 走向 Agent 能力与权限图谱
Agent 时代并没有终结传统软件供应链安全。Injective 事件证明,依赖发布账户、npm 软件包和传递依赖仍然是攻击者成本很低、收益很高的入口。
变化在于,一旦恶意组件进入 Agent 系统,它可能获得比普通应用依赖更大的影响范围。Agent 会主动读取上下文、选择工具、使用凭据并执行操作。一个受污染的软件包、工具描述或项目配置,不再只是被动等待某段代码调用,而可能参与控制 Agent 的决策与执行路径。
因此,组织需要在 SBOM 之外建立一份更接近“Agent 能力清单”的资产视图:
它不仅记录安装了什么,还要记录工具来自哪里;不仅记录存在什么漏洞,还要记录工具拥有什么权限;不仅分析代码调用,还要分析凭据、数据和外部端点之间是否存在可达路径;不仅检查构建产物,还要审计运行时究竟调用了什么。
今天最值得关注的,不是某个模型的编程能力又提高了几个百分点,而是 Agent 正在把软件供应链从代码和依赖,扩展到工具、元数据、上下文、身份权限和运行时执行路径。
模型能力决定 Agent 能完成多少工作。
来源、权限和行为路径,则决定它出问题时能够造成多大的影响。