事件背景与技术特征
2026 年 5 月 19 日,npm 账户 atool 遭入侵,攻击者在 22 分钟内通过自动化脚本发布了 637 个恶意版本,波及 314 个包,其中包括月下载量超 400 万的 size-sensor 和 380 万的 echarts-for-react。此次攻击采用多阶段持久化策略,攻击者在 preinstall 钩子中植入 498KB 的混淆 Bun 脚本,同时通过 optionalDependencies 注入指向 GitHub 仓库孤儿提交的恶意依赖,形成双重 payload 投递机制。
攻击的技术复杂度体现在三个层面:首先,恶意代码利用 Bun 运行时绕过传统 Node.js 安全检测;其次,通过伪造 GitHub 提交作者信息创建 "冒名提交"(imposter commits),利用 GitHub 的对象共享机制托管恶意代码而不需要目标仓库的写入权限;最后,攻击者在 CI/CD 环境中实施横向移动,通过窃取 GitHub Actions OIDC 令牌换取 npm 发布令牌,并使用 Sigstore 签名伪造供应链 provenance。
恶意代码识别机制
针对此类供应链攻击,有效的检测需要覆盖静态分析、行为分析和威胁情报三个维度。
静态代码分析需关注特定代码模式。本次攻击的 payload 具有明确的特征指纹:SHA256 哈希值为 a68dd1e6a6e35ec3771e1f94fe796f55dfe65a2b94560516ff4ac189390dfa1c,文件大小约 498KB,采用多层字符串混淆和动态代码生成技术。检测引擎应识别 preinstall 脚本中调用 bun run 的反常行为,以及对 optionalDependencies 中 github: 协议依赖的异常使用 —— 特别是指向特定 SHA 而非分支或标签的依赖声明。
运行时行为监控需要捕获凭证收集行为。恶意代码扫描环境变量、AWS EC2 元数据服务 (169.254.169.254)、ECS 容器凭证端点 (169.254.170.2)、Kubernetes service account 令牌、HashiCorp Vault 令牌、GitHub PAT 等多种敏感凭证源。检测系统应监控对这些特定 IP 地址的 HTTP 请求,以及对 ~/.aws/credentials、~/.ssh/ 等敏感路径的读取操作。
威胁情报匹配依赖已知的入侵指标 (IoC)。本次攻击创建的外泄仓库遵循 Dune 主题的命名模式 {word1}-{word2}-{number},其中 word1 包括 sardaukar、mentat、fremen 等,word2 包括 sandworm、ornithopter 等。C2 通信通过 GitHub 提交消息中的关键词 firedalazer 触发,命令采用 RSA-PSS 签名验证。检测系统应维护此类特定模式的实时黑名单。
多层自动化响应策略
供应链安全需要从开发环境到生产部署的全链路防护。
安装时拦截是最关键的防御节点。Package Manager Guard (pmg) 作为开源的 npm/pnpm/yarn 安装代理,在 preinstall 脚本执行前评估包的安全性。其核心机制包括:维护实时恶意包数据库,对未知包进行沙箱行为分析,以及实施 "依赖冷却期" 策略 —— 拒绝安装发布时间在可配置窗口内(如 24 小时)的新版本,有效防御利用 semver 范围自动解析到恶意版本的攻击场景。
CI/CD 管道防护需要集成到构建流程。在拉取请求阶段扫描依赖变更,对检测到恶意包的 PR 自动阻断合并。对于使用 GitHub Actions 的环境,应监控工作流文件 .github/workflows/codeql.yml 的异常修改,特别是注入名为 "Run Copilot" 的恶意步骤,该步骤会将 toJSON(secrets) 输出到可被攻击者访问的 artifacts。
AI Agent 运行时安全成为新的防护重点。攻击者在 .claude/settings.json 中注入 SessionStart 钩子,在 VS Code 的 tasks.json 中配置 "runOn": "folderOpen" 任务,实现 AI 代理的持久化劫持。防护系统应监控这些配置文件的变化,阻止执行来自 .claude/setup.mjs 或 .vscode/setup.mjs 的未知 Bun 引导程序。
可落地的工程实践
基于上述检测响应机制,团队可实施以下具体措施:
本地开发环境:部署 pmg 作为 npm 的透明代理,配置冷却期策略拒绝 24 小时内发布的版本。定期扫描 ~/.local/share/kitty/cat.py、~/.local/bin/gh-token-monitor.sh 等持久化文件路径,监控 systemd 用户服务 kitty-monitor.service 和 macOS LaunchAgent com.user.kitty-monitor.plist 的异常创建。
CI/CD 集成:在构建流程中集成威胁情报 API,对每次依赖安装进行实时校验。配置网络策略阻止对 169.254.169.254 和 169.254.170.2 的非必要访问。实施最小权限原则,限制 CI 工作流对 OIDC 令牌的使用范围,禁用不必要的跨仓库访问权限。
监控指标:建立供应链安全仪表盘,跟踪以下关键指标:每日扫描的包数量、检测到的恶意包数量、平均检测提前时间(SafeDep 数据显示平均比公开公告提前 14 小时)、被阻断的安装尝试次数。对使用 @antv 作用域或 atool 发布的包进行重点监控。
应急响应:一旦发现感染,立即轮换所有相关凭证(AWS、GitHub、npm、Docker Hub 等),检查 GitHub 仓库中是否存在符合 Dune 命名模式的外泄仓库,审计 .github/workflows 目录的修改历史,清理 AI 代理配置文件中的恶意钩子。
结论
npm 供应链攻击的检测响应已从单纯的 CVE 扫描演进为针对恶意代码的多维度行为分析。传统的 SCA 工具无法识别 purpose-built 的恶意包,需要结合实时威胁情报、安装时拦截和运行时监控构建纵深防御体系。对于开发团队而言,实施依赖冷却期、部署安装代理、监控 AI 代理配置已成为必要的安全实践。
资料来源
- SafeDep: "Mini Shai-Hulud Strikes Again: 317 npm Packages Compromised" (2026-05-19)
- SafeDep 威胁情报平台: https://safedep.io
- Package Manager Guard (pmg): https://github.com/safedep/pmg
内容声明:本文无广告投放、无付费植入。
如有事实性问题,欢迎发送勘误至 i@hotdrydog.com。