供应链攻击离你有多近

供应链攻击的思路很简单:不直接打你的系统,而是在系统吃进去的东西里做手脚。一个被投毒的依赖包、一个被替换的安装包、一个被篡改的基础镜像,一旦进到你的构建或发布链路,就等于拿到了你生产环境的钥匙。

这类攻击难防的原因在于信任关系:你信任包管理器的源、信任镜像仓库、信任构建机、信任制品服务器,而链条上任何一个环节失守,整条信任都会崩塌。所以供应链安全的本质是把「信任」换成「验证」:不再假设东西没被换过,而是每次使用前都确认它没被换过。

供应链安全的本质:把隐式信任,换成显式验证。
供应链的四个风险点
  • 依赖第三方库被投毒、被劫持。
  • 构建构建机被入侵、脚本被篡改。
  • 制品产物被替换、镜像被污染。
  • 分发下载源被劫持、通道被监听。
软件供应链安全示意:蓝紫渐变背景一条发光链式流水线依次连接四个发光节点方块,每个节点上方悬浮发光挂锁或盾牌,节点间发光连接线串联,扁平科技插画
从依赖到部署,每一个环节都要有一把锁。

依赖管理:锁版本、锁哈希

依赖是供应链上最容易被做文章的一环。常见姿势有两种:一是抢注,把没人用的包名注册下来,等别人误装;二是版本投毒,在看似正常的版本里夹带恶意代码,诱导升级。

第一道防线是锁文件:把每个依赖的精确版本甚至内容哈希固定下来,构建时只认锁文件里的版本,而不是每次拉「最新」。锁文件让构建可复现,也让依赖变更必须显式发生、可被审查。

# 锁文件示例(示意)
dependencies:
  - name: example-lib
    version: 1.2.3
    resolved: https://registry.example.com/pkg
    integrity: sha512-hash-value-here
# 构建时校验哈希,内容对不上就拒绝构建

再配合依赖审计:定期扫描依赖清单,对照已知漏洞库,发现高危依赖就升级或替换。升级本身也要走锁文件,确认变更内容后再合入。

制品与镜像:构建物也要验真

依赖守住了,制品和镜像又成为下一个目标。攻击者可以替换制品仓库里的包、污染基础镜像、或在你构建时注入代码。所以制品要从生成那一刻起就带着身份和指纹。

环节措施防什么
构建机专用、最小化、构建产物可复现构建过程被注入
制品计算哈希、附带来源元数据制品被替换
镜像基于可信基础镜像、最小化安装镜像被污染
仓库访问控制、不可变版本、审计日志仓库被篡改

镜像安全还有一条原则:镜像越小越安全。只装运行时需要的组件,攻击面就小一分;一个只有运行时和必要库的镜像,比装了一堆工具链的镜像难啃得多。

SBOM:给软件一张成分清单

SBOM(软件物料清单)就是软件的成分清单:它列出制品里包含哪些组件、什么版本、来自哪里。平时看似无用,但一旦某个开源组件爆出漏洞,有 SBOM 就能立刻回答「我受不受影响」,没有 SBOM 就只能全量排查。

# SBOM 片段(示意,格式已简化)
{
  "components": [
    {"name": "example-lib", "version": "1.2.3",
     "purl": "pkg:generic/example-lib@1.2.3",
     "license": "MIT"},
    {"name": "util-x", "version": "0.9.1",
     "purl": "pkg:generic/util-x@0.9.1"}
  ]
}
# 每次构建自动生成,随制品一起保存

SBOM 要能干活,得满足三个条件:自动生成,靠人工维护必然过期;随制品保存,发布物的清单要能追溯到具体那个版本;能对接漏洞库,生成只是第一步,定期拿它去比对漏洞才是价值所在。