凌晨三点被叫起来是什么体验。你部署的镜像在客户那边被拦下了,说里面有恶意代码。
查了两个小时,问题不在你的代码里。
在你依赖的某个小包里。
这事没那么玄。供应链安全说白了就一句话——你的软件里有多少东西不是你写的,你其实并不知道。攻击者最喜欢的就是这块你不知道的地方。
名字抢注 最便宜也最有效的打法
我采访过几个做金融和制造业的团队,出事最常见的方式,说出来你会觉得太土了:包名抢注。
场景基本一个模子。某个内部工具的配置文件里写着 @company/xxx-utils,这行字在某个开源项目里露过面。攻击者看到之后,跑到公共仓库上注册一个同名包,版本号填得比你内部的高。你内部是 1.2.3,他就发 9.9.9。构建机器一跑 install,先从公共源找到了,装上了,完事。
不需要零日漏洞,不需要钓鱼邮件。就靠一个版本号。

防这个的办法早就有。私有源做代理,内部作用域强制路由到内网;或者在 CI 里多加一步,检查锁文件里每个包的解析地址是不是预期的那一个。麻烦在于,很多团队知道,没做。为什么没做?因为当初做这件事的人离职了,新来的人不知道这一步是干什么用的。
对,这才最难办。配置是活的,人是走的。
SBOM 生成了一大堆 没人看
这两年客户都在要 SBOM。要得很急,交得很随便。我看过不止一份,几十兆的 JSON,packages 下面几千条记录。然后呢?然后就没有然后了。它进了合规文件夹,从来没进过任何一次运维会的议题。
单看是没用的。SBOM 真正的价值在比对,不在清单。
上个版本和这个版本差了什么,多出来的那个包是从哪条依赖链带进来的,谁带的。这才是能做决策的信息。只存不读,等于给车装了行车记录仪却从来不插卡。

有件事值得做:每次构建的依赖快照跟上一次做 diff,结果推到负责人聊天窗口。不是报警,就是一条消息。绝大多数时候没人理,但真出现异常增量的时候,会有人抬头看一眼。
依赖的引入路径也得管。直接依赖好审,间接依赖最难。一个前端框架能拖两百个包下来,其中一半你连名字都没见过。这不是谁的错,是生态本来的结构。
版本冻结是双刃
有一招很管用:把依赖锁死,锁文件进仓库,改动必须走 PR 审查。攻击者发新版本,你不动就没事。某个投毒窗口期,不少团队就是靠这个躲过去的。
代价也在那儿。锁死不升级,漏洞债一点点攒。半年后想升,发现跨了三个大版本,API 全变,测试挂一片。于是一直不升。
我的分法是两类。进生产产物的依赖锁死,升级走固定节奏,两周一次小步走,别攒。纯开发的依赖可以松一点,它进不了产物。这个划分挺粗糙,但比一刀切强。
流水线本身才是裸奔的那个

攻击者的关注点在往上游走。从打进生产环境,变成打进构建环境。因为打进构建环境一次,所有下游产物同时被污染,而且产物上还带着你的签名。
常见的问题,我反复见到的有这么几个。
自建 runner 跨仓库复用,上一个任务留下的临时文件,下一个任务还看得见;密钥直接写在环境变量里,任何能改构建脚本的人都能把它 echo 出来;第三方 Action 用 @v3 这种可变标签引用,作者哪天改了标签你完全不知道。得固定到 commit 哈希。
最后这条经常被人翻白眼。太麻烦,每次升级都得去查哈希。麻烦在于它确实有效。标签能移动,哈希不能。
再往上是网络。构建机的出网权限该不该收一下?理想状态是只允许走一个代理,代理上有白名单。听着很重,配置一次,长期见效。不少数据外传就是靠构建环节偷偷发出去的。
采购侧也是一样。发给供应商的安全问卷几十页,填的人复制粘贴上一年的答案,收的人扫两眼扫到是就归档。真想问就三个:你的构建环境谁能改;密钥多久轮一次;三个月前那次高危漏洞你几天内修完的。三个问题的答案比三十页问卷有用。
签名和证明链 先别急着上段位
Sigstore、SLSA 这些词热度不低,方向没错。但我劝小团队冷静一点。
签名解决的是这件事:这个产物是不是这条流水线产出的,中间有没有被换过。要做扎实,需要短时凭证,需要隔离的构建环境,需要把密钥管理理顺。一个二十人的团队去追最高等级,多半做成形式——为了过审而签,签完的东西照样从一台谁都能 ssh 的机器上发出去。
更实用的起点:给每个产物算哈希,把哈希记在构建系统之外的、人写不进去的地方。部署的时候比一次。这一步不难,能挡住不少东西。
然后就到了人的部分,这部分技术解决不了。
很多关键库就靠一两个人维护,没工资,靠爱发电。出了事所有人骂他,出钱的一个没有。我不说那句空话。具体做法是:你依赖的库如果业务上真的关键,给它捐点钱,或者派工程师去提 PR,把它内部的测试补一补。再就是跟维护者说话客气点。听起来像废话,你去翻翻那些 issue 区就知道它一点都不废。
出事之后 先回答三个问题
有风声说某个包被投毒了,别急着发公告。先查三件事。
锁文件里有没有它,什么版本,从哪个源解析来的。构建机日志里那个时间段有没有异常出网请求。已经发出去的产物,哈希有没有变。
这三个答案决定你要不要连夜回滚。能不能在半小时内回答出来,取决于前头那些平时看着多余的准备做没做。
回到开头那句话。供应链安全不是能一次性干完的项目,它是一种持续状态,而且注定有缺口。你能做的是把缺口缩小,并且知道缺口在哪。最怕的不是有洞,是不知道自己有多少洞,还觉得这事跟自己没关系。
那才真叫危险。