npm供应链投毒风暴:20分钟317个恶意包窃取云密钥,GitHub紧急吊销6万令牌——凭据管理零信任实战
2026年5月11日,一场代号"Mini Shai-Hulud"的供应链攻击在npm生态中爆发。攻击者接管阿里巴巴AntV维护者账户后,仅用20分钟就向317个npm包推送了630多个恶意版本。一周后Microsoft发布技术报告确认:这次攻击的载荷专门设计用于从GitHub Actions环境中窃取六大平台的CI/CD凭据——包括GitHub Token、AWS密钥、HashiCorp Vault令牌、npm发布令牌、Kubernetes Secrets甚至1Password密码管理器。GitHub随后紧急吊销了61,274个npm细粒度访问令牌。更令人不安的是,攻击者还伪造了SLSA供应链溯源签名,动摇了整个软件供应链证明体系的信任根基。
这不是"某个开发者中了木马"的故事,而是一面镜子——照出了整个软件工业对默认信任的脆弱依赖。

一、攻击全貌:从@antv到你的CI/CD流水线
1.1 时间线
| 时间 | 事件 |
|---|---|
| 5月11日 | 攻击者攻破npm上@antv组织一名维护者账户,开始发布恶意版本 |
| 5月11日(20分钟内) | 向317个npm包推送630+恶意版本 |
| 5月12-13日 | 恶意代码在依赖链中向下游扩散,echarts-for-react(周下载100万+)等顶级包被波及 |
| 5月14-18日 | Microsoft安全团队确认攻击,发布深度技术分析报告 |
| 5月20日前 | GitHub完成清理:移除640个恶意包,吊销61,274个npm令牌 |
1.2 传播链路
@antv维护者账户被攻破
↓
317个npm包 × 630+恶意版本(20分钟内完成推送)
↓
echarts-for-react(100万+周下载)等下游大包自动拉取
↓
数千个项目CI/CD流水线执行 npm install
↓
preinstall钩子自动触发恶意脚本
↓
六大平台凭据被窃取并外泄到C2服务器
一句话概括:你什么都没做错,只是运行了一次 npm install——然后你公司所有的CI/CD密钥就全没了。
1.3 窃取目标清单
Microsoft报告确认,恶意载荷针对六大平台进行系统性凭据窃取:
| 平台 | 窃取手法 | 窃取内容 |
|---|---|---|
| GitHub | 提取GITHUB_TOKEN、扫描ghp_/ghs_前缀令牌、通过/user API验证有效性 |
仓库Secrets、组织级Secrets |
| AWS | 查询实例元数据服务(169.254.169.254)、ECS元数据、遍历所有区域调用SecretsManager:ListSecrets |
IAM凭据、Secrets Manager密钥 |
| HashiCorp Vault | 扫描12+个令牌路径(/var/run/secrets/vault/token等),连接127.0.0.1:8200 |
Vault令牌、存储的密钥 |
| npm | 使用/-/whoami验证令牌、通过OIDC令牌交换发布权限 |
npm发布令牌、包管理权限 |
| Kubernetes | 读取Service Account令牌、枚举命名空间Secrets | K8s集群凭据 |
| 1Password | 与1Password CLI交互,尝试提取主密码、绕过2FA | 密码管理器存储的所有凭据 |
二、技术深潜:恶意代码到底做了什么
2.1 环境门控——只在CI/CD中激活
恶意代码首先进行"环境体检",只在目标环境中执行:
// 解密后的逻辑(原始代码使用PBKDF2+SHA-256加密所有关键字符串)
this.isGitHubActions = process.env['GITHUB_ACTIONS'] === 'true';
this.isLinuxRunner = process.env['RUNNER_OS'] === 'Linux';
// 非目标环境:静默退出,不留痕迹
if (!this.isGitHubActions || !this.isLinuxRunner) {
return; // 开发机器、Mac/Windows Runner:不受影响
}
这意味着:开发者在自己的电脑上跑npm install什么都不会发生,恶意代码只在CI/CD Runner(GitHub Actions + Linux)中激活——这正是凭据最集中的地方。
2.2 进程内存抓取——绕过Secret屏蔽
GitHub Actions会将Secret值自动屏蔽(***),但恶意载荷有一个大招——直接从Runner进程内存中抓取明文密钥:
# 1. 通过/proc扫描定位Runner.Worker进程PID
findRunnerWorkerPIDLinux
# 2. 从进程内存直接提取密钥(绕过GitHub的Secret屏蔽机制)
tr -d '\0' | grep -aoE '"[^"]+":{"value":"[^"]*","isSecret":true}' | sort -u
这个攻击手法的本质是:GitHub的Secret屏蔽只在日志层面起作用,Runner进程内存中密钥是明文的。 攻击者不需要破解任何加密,只需要读取内存。
2.3 三级数据外泄通道
恶意载荷构建了三级冗余外泄通道:
| 通道 | 方式 | 特点 |
|---|---|---|
| 主通道 | HTTPS加密直连C2(t.m-kosche.com:443) |
加密传输,难以检测 |
| 备用通道 | Git Data API(在受害者仓库非保护分支创建blob/commit) | 利用合法API,绕过出站防火墙 |
| 隐蔽标记 | 创建公开仓库,描述为反向字符串"niagA oG eW ereH :duluH-iahS" |
已观察到2,200+个此类标记仓库 |
2.4 SLSA溯源伪造——捅破供应链信任
最具破坏性的是:攻击者伪造了SLSA来源证明。通过Sigstore(Fulcio/Rekor),恶意包被打上了看似合法的供应链证明标签。
这意味着:就算你的组织已经实施了SLSA框架做依赖验证,这次攻击中也可能被绕过。 供应链安全的"信任根"本身被污染了。
三、本质问题:默认信任是整个软件工业的阿克琉斯之踵
3.1 攻击者真正测试的是什么?
不是某个具体漏洞,而是:
代码托管(GitHub)
↓ 默认信任
包管理(npm registry)
↓ 默认信任
自动构建(CI/CD Runner)
↓ 默认信任
云基础设施(AWS/Vault/K8s)
↓ 默认信任
企业核心资产
信任链太长,责任链太散。 开发者享受开源的速度,CI/CD自动拉最新版依赖,但没有人对整条链的安全负责。
3.2 "unzip and run"的致命缺陷
npm的preinstall/postinstall钩子本质上就是"下载后自动执行"——这在任何其他安全模型中都是不可接受的。一条package.json里的"scripts": {"preinstall": "node setup.js"},可以执行任意系统命令。
更致命的是,CI/CD Runner通常拥有:
- GITHUB_TOKEN(仓库读写权限)
- AWS_ACCESS_KEY_ID(云资源完全控制权)
- NPM_TOKEN(包发布权限,可以进一步投毒)
- VAULT_TOKEN(企业密钥库的钥匙)
- 各种数据库密码和API密钥
一旦Runner沦陷,等于把公司所有基础设施的钥匙交给了攻击者。
四、防御方案:在CI/CD中建立凭据零信任体系

面对这类攻击,单点防御不够,需要建立纵深防御的凭据安全体系。
4.1 第一层:消除硬编码凭据
根本问题:为什么你的CI/CD环境里有那么多长期有效的明文Token?
正确做法:
# ❌ 错误:硬编码凭据(攻击者的首要目标)
env:
AWS_ACCESS_KEY_ID: "AKIAXXXX"
AWS_SECRET_ACCESS_KEY: "xxxxx"
NPM_TOKEN: "npm_xxxx"
# ✅ 正确:OIDC临时凭据 + 最小权限
jobs:
deploy:
permissions:
id-token: write # OIDC临时令牌,仅本次运行有效
contents: read
steps:
- uses: aws-actions/configure-aws-credentials@v4
with:
role-to-assume: arn:aws:iam::123456789:role/github-actions-deploy
role-session-name: ${{ github.run_id }}
OIDC的核心优势:没有长期密钥可以偷。 每次CI/CD运行生成一次性令牌,攻击者即使拿到Runner内存也无法复用。
4.2 第二层:凭据管理服务统一管控
将CI/CD中所有凭据统一接入凭据管理服务,实现:
┌─────────────────────────────────────────────┐
│ 凭据管理服务 (SMS) │
│ │
│ ┌──────────┐ ┌──────────┐ ┌────────────┐ │
│ │ GitHub │ │ AWS │ │ Vault │ │
│ │ Token │ │ IAM Key │ │ Token │ │
│ │ TTL: 1h │ │ TTL: 30m │ │ TTL: 2h │ │
│ └──────────┘ └──────────┘ └────────────┘ │
│ │
│ 动态凭据 │ 自动轮转 │ 审计日志 │ 最小权限 │
└─────────────────────────────────────────────┘
↑ ↑
│ 动态获取 │ 按需注入
┌────┴───┐ ┌───┴──────┐
│ CI/CD │ │ 应用容器 │
│ Runner │ │ (Pod) │
└────────┘ └──────────┘
关键能力:
| 能力 | 作用 | 对本次攻击的防御效果 |
|---|---|---|
| 动态凭据 | 不设长期静态密钥,每次请求动态生成 | 攻击者无法窃取"固定的"密钥 |
| TTL自动过期 | 凭据存活时间设为分钟级 | 窃取的密钥很快失效 |
| 自动轮转 | 密钥按策略自动替换 | 即使泄露也无法长期利用 |
| 统一审计 | 所有凭据访问留痕 | 及时发现异常凭据使用行为 |
| 最小权限 | 只授予当前任务必需的最小权限 | 限制泄露后的横向移动范围 |
4.3 第三层:密钥生命周期管理
对于无法完全消除的长期密钥(如CI/CD与外部系统对接的API Key),建立完整的密钥生命周期管理体系:
密钥生成 → 安全分发 → 加密存储 → 使用监控 → 定期轮转 → 安全销毁
│ │
│ 硬件加密机(HSM)保护的密钥根 │ 自动通知 + 强制更新
│ │
└───────────────────────────────────────────┘
统一密钥管理平台 (KSP)
实操层面的四个要点:
- 密钥分级:将密钥分为临时凭据(分钟级TTL)和长期密钥(按天级轮转),分别管理
- 轮转自动化:CI/CD Runner启动时自动从凭据管理服务拉取当前有效凭据,退出时自动回收
- 访问审计:每次凭据访问记录操作者、时间、来源IP和用途,异常行为实时告警
- HSM根保护:密钥管理平台的根密钥存储在硬件加密机中,即使平台本身被攻破,根密钥也无法导出
五、CI/CD凭据加固三步检查清单
你可以在30分钟内完成以下自查:
第一步:盘点(5分钟)
# 检查你的CI/CD环境中暴露了哪些凭据
# GitHub Actions
gh secret list -R owner/repo
# GitLab CI
curl --header "PRIVATE-TOKEN: $TOKEN" \
"https://gitlab.com/api/v4/projects/$PROJECT_ID/variables"
列出所有Secrets,逐个问自己:这个密钥必须长期有效吗?可以改用OIDC吗?
第二步:加固(15分钟)
# 最关键的改动:从长期Token切换到OIDC
# 为每个Cloud Provider配置OIDC Trust
# GitHub Actions示例
permissions:
id-token: write # ← 这是OIDC的核心
contents: read # 只读仓库代码,不暴露写权限
# GitLab CI示例
id_tokens:
AWS_TOKEN:
aud: https://gitlab.com
第三步:验证(10分钟)
# 确认CI/CD Runner的环境变量中没有硬编码凭据
# 在所有CI/CD步骤开头加入检查
- name: Check for leaked secrets
run: |
if [ -n "$AWS_SECRET_ACCESS_KEY" ]; then
echo "WARNING: Static AWS key detected!"
exit 1
fi
echo "OK: No static credentials found"
六、总结
Mini Shai-Hulud攻击暴露的不是npm的漏洞,而是整个软件工业对默认信任的过度依赖。攻击者在20分钟内就完成了从维护者账户到CI/CD凭据的链式入侵,而防御方可能需要数周才能完成凭据轮转。
三条核心教训:
-
"unzip and run"不安全。 你的CI/CD Runner拥有公司所有基础设施的钥匙,但它在每次构建时都会自动执行来自第三方依赖的代码。npm install不是无害的"安装",而是"执行攻击者可能控制的代码"。
-
长期静态凭据是定时炸弹。 GitHub紧急吊销6万多个npm令牌是亡羊补牢——真正的解决方案是用OIDC临时凭据 + 凭据管理服务取代所有长期密钥。
-
供应链信任需要端到端验证。 SLSA溯源伪造暴露了一个根本问题:当信任根本身被污染时,整个信任体系都会崩塌。需要从代码提交、构建到部署的全链路可验证性。
推荐阅读:
- Microsoft Security Blog: Mini Shai-Hulud: Compromised @antv npm packages enable CI/CD credential theft
- GitHub Advisory Database: GHSA-g7cv-rxg3-hmpx
- CISA关于npm供应链攻击的警报(2025年9月)
工具推荐:
npm audit --production/gh secret list/ OIDC配置检查工具
💬 话题讨论:你的CI/CD流水线中有多少长期有效的静态密钥?有没有考虑过切换到OIDC临时凭据?欢迎评论区聊聊你的实践经验。
AtomGit 是由开放原子开源基金会联合 CSDN 等生态伙伴共同推出的新一代开源与人工智能协作平台。平台坚持“开放、中立、公益”的理念,把代码托管、模型共享、数据集托管、智能体开发体验和算力服务整合在一起,为开发者提供从开发、训练到部署的一站式体验。
更多推荐


所有评论(0)