AI 写的依赖包能不能装:供应链风险与五道控制

2026 年 10 月的三起事件把「模型编造依赖名」从一个小毛病,推到了供应链安全的位置上:编造出来的包名正在变成攻击者可以直接占用的安装入口,而智能体让这个入口从「需要人点确认」变成了「无人值守自动拉取」。

AI 安全软件供应链AI 编程研发治理
2026 年 10 月 20 日 · 广州科芃科技有限公司技术团队 · 全文约 8554 字

先说结论:AI 写的依赖不能直接装

2026 年 10 月的三起事件把一个过去被当作"模型小毛病"的问题,推到了供应链安全的位置上:AI 编程工具编造出来的依赖包名,正在变成攻击者可以直接占用的安装入口;而智能体让这个入口从"需要人点确认"变成了"无人值守自动拉取"。

结论先给:依赖安装不是一次普通的构建步骤,而是一次跨越信任边界的特权操作,必须用模型之外的手段来管控。 判断一个包能不能装,依据不能是"模型说它存在",而应当是发布者身份、首次发布时间、仓库关联、下载与依赖量这四项外部事实。

这条线与本站已发布的几篇文章不重复:驾驭工程怎么落地讲的是把智能体纳入研发后如何重建组织级管控框架,属于"制度层";AI Agent 运行时隔离讲的是执行侧的四道边界与权限最小化,属于"运行期";AI Agent 提示词注入怎么防讲的是输入侧的过滤,属于"入口处"。本文只处理一件事:代码进入构建系统之前,依赖是从哪里来的、凭什么可信、要过哪几道闸。它更贴近代码评审怎么做才有效里"依赖变更要作为独立评审项"那条原则,但展开的是一个此前没有系统讲过的具体攻击面。

---

一、这不是"模型偶尔说错",是一条已经成型的攻击链

1.1 幻觉包名有多普遍:USENIX Security 2025 的量化结果

目前公开可查的最系统的一次测量,来自德克萨斯大学圣安东尼奥分校、俄克拉荷马大学与弗吉尼亚理工团队发表于 USENIX Security 2025 的论文《We Have a Package for You!》。研究用 16 个主流代码生成模型、两套提示数据集,生成了 57.6 万个 Python 与 JavaScript 代码样本,结论是:

  • 商业模型的幻觉包名比例至少 5.2%;
  • 开源模型的幻觉包名比例平均 21.7%;
  • 累计记录到 205,474 个互不相同的幻觉包名;
  • 同一模型重复 10 次运行时,43% 的幻觉在 10 次里全部复现,58% 至少复现两次;
  • 81% 的独特幻觉名只出现在 16 个模型中的一个上。

同一研究团队的公开复现仓库给出的整体口径是"被推荐包中 19.7% 为幻觉",并提到分模型差异很大——GPT-4 Turbo 是表现最好的一个(约 3.59%),CodeLlama 7B 与 34B 则高于 33%。

这组数字里最该被注意的不是均值,而是"43% 稳定复现"。一个能稳定复现的名字,就是一个可以被离线预判的名字。 攻击者不需要破解模型,只需要在模型生成之前,用那 20 多万个名字去注册表里占位等着。

需要说明的是,这些数字来自受控研究环境中的批量生成任务,不是任何一家企业自身代码库的实测发生率。它的价值在于证明这个行为真实、可测量、可预测,而不是预测某个具体项目的风险概率。

1.2 从"名字错了"到"自动执行":slopsquatting 的定义与命名来源

当攻击者预先注册那些模型会编造出来的包名,等着开发者或智能体去安装时,这种攻击被称为 slopsquatting。这个术语由 Python 软件基金会的 Seth Larson 在 2025 年 4 月提出,经 Ecosyste.ms 的 Andrew Nesbitt 推广,名字本身就把两件事说清楚了:AI 生成内容常被批评为 slop(垃圾),而占用名字等待受害者上钩则是 squatting(抢注)。

它与传统的 typosquatting(仿冒近似名,如把 requests 写成 reqeusts)有一个关键差别:仿冒名必须与真名相近,而幻觉名不需要与任何真实包相似——它是从零编出来的一个合乎命名惯例、看起来完全合理的名字。这一点后面会再展开,它直接决定了几种常见防御手段为什么无效。

MITRE ATT&CK for AI 把这一手法单列为 AML.T0060「Publish Hallucinated Entities」,覆盖的不只是包名,也包括网站、公司名、邮箱地址等一切"模型编出来的、攻击者可以先占位的实体"。OWASP 的大模型应用风险清单中,LLM09「Misinformation」把"推荐不存在的代码库"列为不安全代码生成的典型例子,而 LLM03「Supply Chain」则给出了供应商审查、组件清单签名与完整性校验这组通用控制项。

1.3 三个已经落地的样本

样本一:huggingface-cli(2023 年)。 在 slopsquatting 这个词出现之前,安全研究员 Bar Lanyado 就注意到模型在被问及如何安装 Hugging Face 命令行工具时,会反复推荐一个叫 huggingface-cli 的包——而正确的安装路径是 pip install -U "huggingface_hub[cli]",那个名字对模型来说不直观。他以概念验证的名义注册了这个空包,三个月内下载量超过 3 万次,全部来自相信 AI 建议的人。这个案例后来还出现了后续:一个大型技术组织的开源仓库 README 中原样出现了这个错误包名且未被纠正(该细节来自第三方分析文章转述,非当事方发布)。

样本二:react-codeshift(2026 年 1 月)。 这是目前公开资料里传播链条最完整的一次。2025 年 10 月,一个公共仓库的某次提交一次性加入了 47 个模型生成的 agent skill 文件,横跨 14 个插件,其中两个 skill 要求智能体执行 npx react-codeshift。这个名字是模型把两个真实存在的工具 jscodeshift(JavaScript codemod 工具包)与 react-codemod(基于前者的 React codemod)拼接出来的产物,现实中从未存在过。

据 Aikido Security 研究员 Charlie Eriksen 的披露,等到 2026 年 1 月他审计 npm 未被认领的包名时,这个名字已经出现在 237 个仓库中——约一百个直接 fork、一位用户把它复制进自己 30 个仓库、若干次目录结构重组,以及一份日文技术文档的直译。Eriksen 于 1 月 14 日以防守目的自己注册了这个名字。值得注意的是他披露的后续遥测:这个包没有像典型的死 phantom 包那样首日下载六七十次然后归零,而是稳定维持在每天一到四次下载,Aikido 归因于仍在一遍遍执行这些 skill 的智能体。

样本三:CIE LCH 色彩空间任务实测。 一次公开的小规模实验里,五个主流助手在处理 CIE LCH 色彩空间相关任务时全部推荐了不存在的库:ChatGPT o3 给出 cie-lch-utils,Claude Sonnet 4.5 给出 colourscie,Gemini 2.5 Pro 给出 pyciecolor 与 lch-parser,DeepSeek V3.1 给出 ciecolor、color-space-utils 与 pylch,而 Cursor 在完全不提示的情况下写出了带不存在 import 的代码。五个里中了五个。

---

二、2026 年 10 月的三起事件:风险从"编名字"升级为"劫持智能体"

前文的样本都属于"名字错了"这一类。10 月发生的三件事,把风险推到了另一个层面:攻击目标不再只是骗你装一个包,而是直接接管你的智能体本身。

2.1 REF8801:恶意包改写智能体的模型出口与 MCP 配置

2026 年 10 月 12 日,Elastic Security Labs 披露了编号 REF8801 的攻击行动。该行动伪装成一个名为 Apex Accelerator 的 Web3 创业加速器,宣称提供免费的 Claude 与 Gemini 额度、编程工具与智能合约审计,站点上挂着 200 多个项目组合与 1.24 亿美元融资额度的说法,并通过 X 平台与 TOKEN2049 线下活动引流,最终要求开发者安装两个 npm 包:@apexacc/cli(对外称 AI 编程助手 "Apex Copilot")与 @apexacc/audit(对外称安全审计工具)。

据 Elastic 的报告,这个包做的不是单纯偷凭证,而是同时从三个方向接管智能体:

攻击面具体做法后果
模型出口覆写 OPENROUTER_BASE_URL,指向攻击者控制的域名智能体读到的每个文件、发出的每条提示、每次工具调用结果都流向攻击者基础设施
MCP 配置向 ~/.apex/agent/mcp.json 写入 apex-copilot 条目,指向一个带 8 个工具的远程 MCP 服务器攻击者获得一个可以把指令永久注入智能体上下文的地址
审批策略捕获的源码把工具审批默认设为 "yolo" 模式智能体执行命令时不再向人确认

Elastic 对第一项的表述值得原样记住:"供应商仍然标注为 OpenRouter,而实际的网络对端是一台攻击者控制的服务器。" 也就是说,从界面和配置上看一切正常,人在键盘前看到的始终是一个能正常工作的编程助手——但智能体自己的推理上下文已经被完整转走了。

同一份披露还提到,@apexacc/cli 的 1,363 个文件中有 1,351 个与开源的 Oh My Pi 智能体完全一致,攻击内容全部是新增部分;而 @apexacc/audit 暴露了一个带 18 个"安全工具"的 MCP 服务器,每一个都返回编造的结果——它给出了一份"已修复"的 Slither 报告和一句"NOT A HONEYPOT"结论。一个会告诉你"你的合约是安全的"假审计工具,本身就是一套针对开发者的社会工程。

另需说明的是,上述文件数量对比来自第三方安全博客对 Elastic 报告的转述,本文未逐项复核原始报告。

2.2 Tensorlake 0.5.144:官方包被投毒,且来源证明校验失效

2026 年 10 月 7 日 01:20 UTC,一个以维护者名义的恶意提交进入 tensorlake-ai/tensorlake 主分支;10 月 8 日,同名 npm 包 0.5.144 从同一个仓库发布,携带混淆后的恶意载荷。攻击者使用的是 Shai-Hulud 家族窃密蠕虫的 Mini 变种,通过 preinstall 脚本在开发者终端、CI 环境、Kubernetes 与云环境中执行,窃取 npm 令牌、GitHub 个人访问令牌、AWS/GCP/Azure 云密钥与 HashiCorp Vault 凭据。悬镜安全情报中心在 10 月 8 日 9:13 监测到该事件并向订阅用户推送预警;另有第三方分析称从恶意提交进入主分支、到发布、再到研究人员发现,整个过程只隔了约 11 分钟。

这个案例里有两点值得单独拎出来。

第一,沙箱边界在这里不生效。 Tensorlake 提供的正是"运行 LLM 生成代码的隔离沙箱服务",其 npm SDK 月下载量在 11 万次左右(另有第三方统计称周下载约 1.2 万次,两个口径不一致,此处并列而非取一)。按AI Agent 运行时隔离那篇文章的框架,沙箱隔离的是不可信的生成代码;而针对该 SDK 安装阶段的恶意代码,直接运行在开发者主机、应用服务器或 CI/CD 构建节点之上。SDK 投毒先于沙箱隔离边界生效,并且天然继承了部署凭证等各类敏感权限。

第二,也是更值得警惕的一点:来源证明在这里完全失效。 悬镜的分析明确指出,恶意版本构建自项目真实主分支,携带有效的 npm provenance 来源证明,SLSA 签名链路完整——任何信任 provenance 的准入策略在这次事件中都会失效。 换句话说,"发布链看起来是干净的"这件事本身,在维护者账号被攻破的场景下不再构成安全证据。

这也是继 Mastra 智能体开发框架投毒事件之后,又一起针对 AI 智能体开发工具链的蠕虫式供应链攻击。Shai-Hulud 家族此前的攻击波次还包括 keyv/cacheable 与 @antv(波及周下载量百万级的 echarts-for-react)。

2.3 SlugFest:包名没被抢,但"发布者身份"能被冒用

2026 年 10 月 13 日,Bloom Security 的 Golan Myers 披露了 npm trusted publishing 中的一个缺陷 SlugFest。

npm 的 trusted publishing 机制(2025 年 7 月面向所有人开放)本意是去掉长期令牌:发布时由 GitHub Actions 签发一个描述本次运行的短期 OIDC 令牌,npm 拿它与绑定比对后返回发布凭据,全程没有可窃取的长期密钥。问题出在绑定记录什么——npm 在首次成功发布之前,只记录了仓库的可读地址(owner/repo 这个 slug),而不是不可变的 GitHub 仓库 ID。 名字可以易主,ID 不能。当维护者改名、转移或删除了仓库,这个 slug 就被释放,任何人重建一个同名仓库即可满足那条信任配置,用一个不属于自己的仓库为别人的包发布新版本——不需要窃取任何凭据。

Bloom 的扫描结果是:超过 1,500 个存在暴露的包,累计下载量超过 1,000 万次,每月超过 100 万次。这个数字的分母不是 npm 上的全部包,而是配置了 trusted publishing 的那部分包——后者规模小得多,所以问题的相对严重性更高。Bloom 同时表示不公布受影响包清单,因为问题当时仍普遍存在。时间线是:6 月 6 日通过 GitHub HackerOne 报告,6 月 9 日被分类确认,7 月 8 日收到"正在修复"的最后回复,此后 6 次跟进与一次调解请求均无回应;在发布前重跑攻击测试时发现 npm 已实施修复,团队随后致歉并说明修复落在 2.10 版本。

修复方式是:48 小时内没有发布事件的信任配置自动失效,配置在完成首次成功发布后才被"验证"并豁免该过期规则;同时 npm 开始拒绝来自 GitHub Actions issue_comment 事件的 trusted-publishing 令牌,并叠加在既有的 pull_request_target 限制之上。有意思的是,Myers 建议的方案(信任建立时就把 slug 解析为不可变的 repository_id 与 repository_owner_id 并在换取凭据时做精确相等校验)并非机制层面的缺陷修复——PyPI 的 Warehouse 早就是这个做法,也就是说这里是一次明确的实现遗漏,而非设计问题。

Bloom 报告中还有一组直接指向智能体的统计,值得单独看:一个编程智能体平均每月安装约 70 个包,开发者机器上可接近 350 个;按类型不同,单个智能体每天安装 0.3 到 1.2 个包,开发者机器平均每天 2 到 3 次直接安装;平均每个终端运行 3 个智能体,开发者机器上可能超过 5 个。这些数字不含传递依赖,因此真实软件足迹更大。Bloom 提到曾拦截过某个客户智能体尝试安装受影响包的行为,并提出了一个常被忽略的盲区:恶意发布可以携带指向攻击者自己仓库的 attestation,而有些系统只校验"attestation 是否存在",不校验"它是否来自预期的维护者仓库"。

---

三、为什么智能体让风险放大了一个量级

上面三起事件如果发生在人类开发者身上,是可以被发现的。智能体让它们变难发现,原因有四个,且都跟"人"在链路里的位置有关。

3.1 智能体绕过的是"人审"这一环

传统供应链攻击要成功,需要骗过一个人的一次点击。人类开发者在执行安装前会做一件机器不做的事:读一遍这个名字。而在智能体流程里,安装指令出现在智能体执行的一个步骤中,写在一份没人会打开的日志里;唯一的确认提示对智能体来说,和它执行的其它步骤一样,被同一种方式回答掉。Bloom 用一个比喻解释 SlugFest 的性质:"这就像一把只核对门牌、不核对房主是谁的锁;房主搬走了,谁搬进来谁就拿到钥匙。" 而当攻击者通过被回收的名字发布恶意版本时,Bloom 的表述是它"会被拉进来,在没有人参与的情况下运行"。

3.2 npx、uvx、pipx:连依赖清单都不留

这三个命令会执行包而不把它写进依赖文件。 没有依赖条目,没有 lockfile 行,什么都没有留给后续扫描去对账——包被拉取并直接运行了。确认提示成了唯一的闸门,而如前所述,智能体不会认真读这个名字。

这一条特别值得单独强调,因为它意味着前面列出的很多控制(锁文件哈希校验、SBOM、SCA 扫描)在 npx 这条路径上是结构性失效的,不是"记得配置"就能补上的。这也是这条路径被称为"最锋利的边缘"的原因——它是依赖工具本身看不见的那一类。

3.3 技能文件与配置:幻觉名字的传播载体

仓库源文件里的幻觉名字是一个仓库的 bug;技能文件、AGENTS.md、规则文件里的幻觉名字是一个会被 fork、被翻译、被 vendored 的 bug,且在原作者离开之后还会继续叫。 react-codeshift 案例里,47 个 skill 文件出现在一次提交中,横跨 14 个插件,随后扩散到 237 个仓库并被翻译成日文——这条扩散路径与人是否仔细读过代码没有关系。

3.4 自动拉最新版:把发布瞬间变成投毒窗口

当智能体自动解析并安装最新可用版本时,一次恶意发布从"需要人决定是否升级"变成"自动进入构建"。Slope 这条链路上还存在一个时间维度:Bloom 统计到开发者机器平均每天有 2 到 3 次来自智能体的直接安装,这意味着一个被劫持的包名,其触达频率等于智能体的工作频率。

---

四、五道控制:把"装不装"的决定权从模型手里拿回来

所有有效的控制都位于模型之外。这不是妥协,而是工程上的必然——原因在第三节已经说过:让模型更小心并不能关掉这个缺口。

4.1 第一道:源收敛(代理仓库与白名单)

让构建智能体无法直连公共索引。 开发者与 CI 应当通过内部仓库或代理安装依赖,代理只提供已批准的包,任何新名字触发一次审查请求而不是一次静默拉取。这一条单独就能把大部分尝试变成"被人看到的、被拦下的请求",也是这五道里唯一在规模上成立的一条——它把判断标准从"有没有人注意到"换成了"它在不在名单上"。

JFrog 在 2026 年推出的 Agent Package Resolution 是这条思路的产品化形态,分三层执行:会话引导(在每次会话开始时把各类型受管包的 Artifactory 地址给智能体)、持久化包管理器配置(一次性把本地包管理器绑定到指定仓库,覆盖 postinstall 脚本与批量拉取等间接安装路径)、服务端强制(无论智能体是否遵循引导,每个包都必须过同一套策展与扫描策略,并完整记录每一次下载、拦截与策略判断)。

Semalt 的搜索与 Web 分析专家 Iurii Iakovenko 在 2026 年 8 月的分析中把这一点讲得更直接:Cursor、Claude Code 这类智能体允许用户用自然语言描述意图,由智能体自主决定需要哪些包并直接从 npm、PyPI、Maven、Go、Docker Hub、Helm、NuGet 等公共注册表检索——这不是边缘情况,而是默认工作模式。传统供应链治理模型恰恰假设"依赖经由策展仓库流动、策略决定访问、每个动作都被记录以供审计",而智能体驱动流量直接绕过了这些路径。这一治理缺口随智能体编码工具的普及而扩大。

同一份分析还引用了 JFrog《Software Supply Chain Security State of Union 2026》的数据:2025 年恶意 npm 包活动增长 451%,识别出超过 171,000 个独立恶意包。

4.2 第二道:时间闸(最小发布年龄)

拒绝"太年轻"的包。 pnpm 的 minimumReleaseAge 默认 24 小时,多数生态通过代理都能做到等价效果。云安全联盟(CSA)的研究建议是把过去 30 到 90 天内注册的包标记出来强制人工看一眼。

这条控制的逻辑很直接:抢注必须在需求出现之前完成,而需求出现的时间不可预测。 一个成熟度延迟会强迫攻击者提前暴露自己——他必须在你需要这个名字之前很久就把包铺好,而这给了发现它的窗口。

4.3 第三道:变更闸(新依赖必须经人工批准)

把"新增一个不在名单上的依赖"放到审批策略里,让它停下来找人。 或者让它经过一个分类器:先查注册表记录(首次发布时间、版本数、是否关联源码仓库、发布者是否只有这一个包),再决定放行还是拦下。

Bloom 给包维护者的自查建议同样属于这一层:对自己的每个包运行 npm trust list,确认配置的仓库地址仍解析到自己控制的仓库;改名或转移后删除旧绑定并重建;把仓库删除、转移、改名当作一次凭据吊销事件来处理——如果删了绑定仓库且不打算在原地址重建,就先把信任绑定删掉;并且把"自己没发起过的发布事件"当作已被利用的证据来看待。

落到 CI 上的不变式是一句话:不允许任何模型生成的 token 序列,仅凭模型自身的权威就成为一条已安装的依赖。

4.4 第四道:执行环境隔离

在没有生产凭证的环境里安装,默认禁用安装脚本(生态允许时),并按最小权限原则只给智能体完成当前任务所需的访问。agent-patterns 与 Safeguard 的实践建议里都把这一条列为独立控制点,理由与 Tensorlake 案例完全一致:安装阶段的代码运行在开发者主机、应用服务器与构建节点上,它继承的正是部署凭证。

这条与本站AI Agent 运行时隔离那篇讲的四道边界是同一套原则在不同阶段的应用——那篇讲的是智能体运行任务时能碰到什么,本文讲的是它拉依赖的那一刻能碰到什么。

4.5 第五道:清单核对(发布者、年龄、仓库关联)

这一道是前三道漏掉之后的兜底,也是唯一能发现"前四道都放行但仍有问题"的检查。 核对对象是外部事实,不是模型的判断:首次发布时间、维护者历史、能否解析的源码仓库链接、发布者名下是否只有这一个包、下载量与下游依赖数是否符合这个包的合理量级。

Cloud 安全联盟提到的经验判据很实用:一个上周才发布、只有一个版本、没有仓库链接的包,值得一个人看一眼。反过来,扫漏洞的工具在这条链上是盲的——新注册的恶意包还没有对应的公告,SCA 的匹配逻辑天然覆盖不到它。这不是"要不要开扫描"的取舍问题,而是"扫描不能替代前四道"的定位问题。

一个具体的对照例子:当智能体在实现 PDF 导出功能的中途试图安装某个由两个知名 PDF 库拼接而成的包时,注册表反馈是"9 天前首次发布、只有一个版本、无关联仓库、带 postinstall 脚本",分类器拦下安装并询问开发者;开发者搜这个名字,发现背后没有项目,于是把智能体指向真正的库。整个绕路成本是四分钟。如果没有这道闸,那段脚本会在一个持有部署令牌的容器里执行。

4.6 五道控制的分工对照

控制拦截的是有效性来源主要代价
源收敛(代理 + 白名单)任何不在名单上的包名不依赖任何人注意到需要维护代理与名单
时间闸(最小发布年龄)抢注型新包攻击者必须提前暴露新库接入变慢
变更闸(人工批准)智能体自主新增依赖把决定权交回人增加交互轮次
执行隔离安装脚本的破坏力限制爆炸半径需要沙箱与凭证管理
清单核对前四道放行但来源存疑的包核对外部事实需定期扫描与复核

---

五、为什么"让模型更小心"不能作为答案

一个自然的疑问是:模型在变强,这个问题会不会自己消失?现有数据给出的答案是——发生率在下降,但共享的攻击面在变大。

模型侧确实在改善。 Trend Micro 的 Sean Park 在 2025 年 6 月发表的测试中发现,推理能力加上实时网络搜索大致能把编码智能体编造包名的频率减半;同时他也指出,即便让智能体对每个候选依赖都去比对实时文档与搜索工具,在最难的提示上仍会有少数编造的名字漏过去。换句话说,这条路的收益是"减半",不是"清零"。

而 43% 这个数字决定了它无法被清零。 只要幻觉名能在同一模型上稳定复现,攻击者就可以做离线枚举——用批量生成的方式把可预测的名字先捞出来,再决定占哪些。模型越便宜、越快、越普及,可枚举的规模越大。Bloom 的表述把这个关系讲得很清楚:风险在智能体自动解析并安装最新版本时会放大,因为一个被劫持的名字触达的频率等于智能体的工作频率。

有一类相邻风险也在同期被量化。Veracode 的 2026 年生成式 AI 代码安全报告称,受检样本中 45% 在超过 100 种方式里引入了 OWASP 前十类弱点。2026 年 10 月 14 日,一次性披露了七个跨 npm 与 pip 的操作系统命令注入漏洞,其中六个 CVSS 3.1 评分为 9.8,根因相同——用户可控的文件路径与参数被未中和地插入 shell 命令;报告指出 pypdftk、whisper-node、transcribe2texts、nodejs-whisper 四个包当时没有已知修复方案。同期还有 Claude Agent SDK 的 resume 选项参数注入可导致任意命令执行,以及 LMCache 多进程传输在反序列化不可信消息时形成 RCE,两者都落在 AI 工具链这个正在快速扩张的攻击面上。

这些事件共同说明一件事:依赖与构建链路的风险,已经不再主要由"某个依赖有已知漏洞"来衡量,而是由"这个依赖是怎么进来的、谁批准的、发布者身份能不能被冒用、构建节点上握着什么凭证"来衡量。 这是两类不同的问题,需要两类不同的控制。

---

六、给不同规模团队的落地清单

6.1 三人以下的小团队

资源有限时,优先级应该压到前三项,其余先不做:

优先级动作为什么先做
1锁文件入库、启用哈希校验,CI 中禁止锁文件变更与依赖清单变更不同步发生成本最低,收益最大,且完全不需要额外基础设施
2在 CI 里加一条检查:新依赖必须显式列出,并附上为什么需要它、注册表页面链接多数团队的第一道真实防线,改动量在几十行脚本内
3禁止在智能体会话中直接执行 npx、uvx、pipx,改为显式写进依赖清单消除"连清单都不留"这条结构性盲区
4开启并提交 SBOM为事后追溯留下基线
5为自己发布的包配置 2FA,并定期核对 trusted publishing 绑定保护自己也在链上的团队

6.2 有专职研发流程的成长型团队

在上一节基础上增加源收敛:建内部代理,只允许名单内包通过;同时把"新增依赖"接入审批流,并对智能体 shell 会话默认屏蔽公网安装。在此之上补两条组织动作:把依赖变更当作代码评审中的独立条目来读,而不是当成代码 diff 周围的噪声;以及定期扫描智能体自己生成的文档、README 与 skill 文件里的安装命令——那是一次幻觉变成几百次安装的唯一扩散路径。

Bloom 对安全负责人的建议值得原样采纳:审计的不应止于传统软件包,还包括扩展、MCP、skill、应用、插件与仓库,因为这类问题并不局限于软件包。同时要执行供应链防火墙来把关什么可以装进环境,并制定明确的智能体使用策略。

这也正是本站MCP 与 A2A 有什么区别那篇文章的一个延伸结论:MCP 服务器的安装应当与新增 npm 依赖接受同等强度的审查。 REF8801 里那个带 18 个假工具的恶意 MCP 服务器,就属于这条建议的现实注脚。

6.3 有合规要求的组织

再加上四件更正式的事:

把 AI 辅助开发写进安全开发生命周期文档。 TechTarget 在其 slopsquatting 专题中引用的多方说法里,反复出现同一个判断:绝大多数组织尚未在 SDL 文档中明确处理 AI 辅助开发这件事。文中引用的 Bugcrowd、Trey Ford 的表述是,这类风险"还没有出现在我接触的大多数组织的董事会材料、审计清单或网络保险问卷里,因为它不契合任何既有分类";Black Duck 的 Li Zhao 认为主要缺口在依赖治理与验证——多数组织能扫已知组件与漏洞,但缺少在 AI 建议的依赖进入源码仓库、构建系统或 CI/CD 之前核验其合法性、来源与可信性的控制。

建立 SBOM 归因并准备事件报告流程。 欧盟《网络韧性法案》第 14 条关于被利用漏洞与严重事件的报告义务已于 2026 年 9 月 11 日开始适用,含数字元素的产品制造商须在知悉后 24 小时内提交早期预警通知,随后提交更详细报告;完整的核心网络安全要求与 CE 标识义务自 2027 年 12 月 11 日起适用。同时期,美国 OMB 2026 年 1 月发布的 M-26-05 备忘录把联邦 SBOM 归因转为基于风险的思路。

审计已安装软件而不只是已声明依赖。 这与 Bloom、TechTarget 两方口径一致,而且现在有了具体理由:攻击面已经从包扩展到 MCP 服务器、智能体配置与模型端点。

为智能体的网络出口设基线并告警。 建立"预期 API 端点"清单(模型服务提供商的域名),对任何偏离告警——尤其对不熟悉的代理域名或 IP。REF8801 的核心手法就是改写端点,而这类改写在事后取证里留下的痕迹是明确、可检测的。

---

七、结语:把"装包"重新定义成一次特权操作

回到开头的结论。AI 编程把依赖安装这件事的性质改了,但没有改变一件事:一个名字进入构建系统,意味着有人愿意为它的来源背书。 这个"愿意"过去由人承担,现在经常由模型代替人做出,而模型的判断依据是自己的训练分布,不是任何外部事实。

所以真正的控制点不在提示词里,在流水线上:把源收敛到可代理的地方,把时间当作筛子,把变更审批留给把人,把安装放进没有生产凭证的环境,再把"这个包的发布者、年龄、仓库关联"当作必须核对的事实。

SlugFest 那个比喻其实可以直接搬到工程实践里:一把只核对门牌、不核对房主是谁的锁,房主搬走了谁搬进来谁就拿到钥匙。 依赖治理的大部分工作,说到底是在把这把锁换成既核对门牌也核对房主的版本;而在智能体能够自己按下按钮的今天,这件事的优先级已经和"谁能访问生产数据库"放在同一层了。

如果你正在评估自己团队的这条链路,可以从我们的工程能力说明与软件研发服务入手了解我们在交付中的做法;如果是 AI 应用本身的建设问题,人工智能应用开发与交付流程里记录了更完整的实施路径;如果是审计与验收环节,数字化项目的验收标准怎么定提供了一份可直接套用的检查项清单。

关于本文:本文由广州科芃科技有限公司技术团队撰写,基于公开行业信息与我们在软件、人工智能应用开发中的工程实践整理,用于说明该主题下的问题结构与应对方法;文中不包含客户名称与未公开的项目细节。
FAQ

常见问题

AI 生成的依赖包可以直接安装吗?

不建议直接安装。USENIX Security 2025 的研究显示,商业模型生成的包名中至少 5.2% 是不存在的,开源模型平均达 21.7%,累计记录到 205,474 个互不相同的幻觉包名,且 43% 的幻觉在同一模型重复运行时全部复现——这意味着名字可被离线预判并提前占位。正确做法是让构建通过内部代理与白名单安装,新依赖进入审批流程,并在无生产凭证的环境中完成安装。

slopsquatting(AI 包名抢注)是什么,和 typosquatting 有什么区别?

slopsquatting 指攻击者预先注册 AI 模型会编造出来的包名,等着开发者或智能体去安装。术语由 Python 软件基金会的 Seth Larson 于 2025 年 4 月提出,经 Ecosyste.ms 的 Andrew Nesbitt 推广。与传统仿冒近似名不同,幻觉包名不需要与任何真实包相似——它是从零编出来但符合命名惯例的名字,因此基于编辑距离的仿冒检测对它无效。MITRE ATT&CK for AI 将该手法列为 AML.T0060「Publish Hallucinated Entities」。

为什么智能体会让依赖供应链风险显著放大?

有四个原因:一是智能体绕过了人类开发者「读一遍包名」这一步,安装指令出现在没人会打开的日志里;二是 npx、uvx、pipx 会执行包而不写入依赖文件,锁文件与 SBOM 等控制在这条路径上结构性失效;三是技能文件与 AGENTS.md 会把幻觉名字随 fork、翻译一起扩散;四是智能体自动拉取最新版本,使恶意发布的触达频率等于智能体的工作频率。Bloom Security 测得单个编程智能体每月安装约 70 个包,开发者机器上可接近 350 个。

2026 年 10 月有哪些值得关注的真实案例?

三起:其一,Elastic Security Labs 于 10 月 12 日披露的 REF8801,伪装成 Web3 加速器的恶意 npm 包同时改写了智能体的模型出口(覆写 OPENROUTER_BASE_URL)、注入了指向攻击者的 MCP 服务器配置、并把工具审批默认设为 yolo 模式;其二,Tensorlake 官方 npm 包 0.5.144 被 Shai-Hulud 家族 Mini 变种投毒,恶意代码经 preinstall 脚本直接运行在开发者主机与 CI 节点上,且携带完整有效的 provenance 签名,使来源证明校验失效;其三,Bloom Security 于 10 月 13 日披露的 SlugFest,npm 信任发布记录的是可被回收的仓库名而非不可变 ID,1,500 多个包暴露于身份冒用,攻击者无需窃取任何凭据。

企业该怎么管控 AI 生成的依赖?

五道控制按顺序落地:①源收敛,让构建智能体无法直连公共索引,只经内部代理与白名单安装;②时间闸,拒绝发布过早的包,pnpm 的 minimumReleaseAge 默认 24 小时是可参考的量级;③变更闸,把「新增不在名单上的依赖」设为需人工批准或经注册表记录分类器放行;④执行隔离,在无生产凭证的环境安装并默认禁用安装脚本;⑤来源核对,核查首次发布时间、维护者历史、能否解析的源码仓库链接等外部事实,作为前四道的兜底。

有了 SCA 扫描和 SBOM,还需要这些控制吗?

需要,两者覆盖的是不同问题。SCA 的工作方式是把包匹配到已知漏洞公告,而新注册的恶意包还没有对应公告,因此这条路径天然是盲的。Veracode 2026 年报告还显示,AI 生成代码引入的弱点中大量属于逻辑与意图层面问题,单纯基于模式的分析难以发现。此外 Bloom Security 指出,恶意发布可以携带指向攻击者自己仓库的 attestation,只校验「attestation 是否存在」而不校验「它是否来自预期维护者仓库」的系统仍会被绕过。所以扫描是必要环节,但不能替代前四道控制。

聊聊你的行业场景

把你的业务场景和期望讲清楚,我们先判断技术上怎么实现最稳,再谈报价与周期。