14
0

Agent 时代的供应链风险,不只在代码里,也在工具、依赖和运行权限里

2026-07-10

过去谈软件供应链安全,我们通常会画出这样一条链路:源代码、第三方依赖、构建系统、软件包、部署产物。相应的防御手段也围绕这条链展开:用 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 被植入恶意逻辑。恶意代码被包装成遥测功能,在应用调用 fromMnemonicfromHex 等正常的钱包密钥处理函数时,收集助记词和私钥并向外发送。它不是在安装阶段立即执行,而是隐藏在正常业务路径中。

这次事件还有一个重要细节:攻击者不只发布了一个恶意 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 能完成多少工作。

来源、权限和行为路径,则决定它出问题时能够造成多大的影响。

Comments