文章摘要
NPM生态系统遭遇严重供应链攻击,包括@ctrl/tinycolor在内的40多个包被恶意软件感染,该软件具有自我传播机制,能自动感染下游包,形成连锁反应。攻击针对Linux/macOS开发者,利用Node.js模块进行侦察、数据收集和传播。受影响的版本已从npm移除,事件由社区成员发现并报告。
文章总结
NPM生态系统遭受重大供应链攻击:@ctrl/tinycolor等40多个包被入侵
2025年9月16日,NPM生态系统再次遭遇严重的供应链攻击。此次攻击波及了每周下载量超过200万次的流行包@ctrl/tinycolor,以及40多个由不同维护者管理的包。攻击者通过植入恶意代码,利用自我传播机制自动感染下游包,导致整个生态系统出现连锁反应。目前,受影响的版本已从NPM中移除。
此次事件由@franky47发现,并通过GitHub issue及时通知了社区。
攻击技术分析
攻击通过多阶段链展开,利用Node.js的process.env获取凭证,并使用Webpack打包的模块实现模块化。攻击的核心是一个约3.6MB的压缩文件bundle.js,该文件在npm install期间异步执行,可能是通过被篡改的package.json中的postinstall脚本触发的。
自我传播机制
恶意代码通过NpmModule.updatePackage函数实现自我传播。该函数查询NPM注册表API,获取维护者拥有的最多20个包,并强制发布补丁,从而在这些包中注入恶意代码,形成连锁感染。
凭证窃取
攻击者利用开源工具如TruffleHog扫描文件系统,寻找高熵的密钥。它通过正则表达式(如AKIA[0-9A-Z]{16})搜索AWS密钥,并转储整个process.env,捕获诸如GITHUB_TOKEN和AWS_ACCESS_KEY_ID等临时令牌。此外,恶意代码还通过AWS Secrets Manager和Google Cloud Platform的@google-cloud/secret-manager API枚举云平台密钥。
持久化机制
恶意代码通过注入GitHub Actions工作流文件(.github/workflows/shai-hulud-workflow.yml)实现持久化。该工作流在推送事件时触发,并将仓库密钥通过${{ toJSON(secrets) }}表达式外泄到命令与控制端点。
数据外泄
恶意代码将收集到的凭证汇总为JSON格式,并通过GitHub的/user/repos API上传到名为Shai-Hulud的公共仓库。
攻击机制
攻击始于将复杂的JavaScript压缩包注入到受影响的包中。该恶意代码使用Webpack模块化组织操作系统工具、云SDK和API封装器,包含六个核心模块,分别负责系统信息收集、凭证窃取和传播等功能。
受影响包列表
包括@ctrl/tinycolor、angulartics2、@ctrl/deluge等40多个包。用户应立即检查并移除这些受影响的包,并采取以下措施:
- 移除受感染包:使用
npm ls @ctrl/tinycolor检查并移除受影响的包。 - 清理受感染仓库:删除恶意GitHub Actions工作流文件,并检查是否有名为
shai-hulud的分支。 - 轮换所有凭证:包括NPM令牌、GitHub个人访问令牌、AWS IAM凭证等。
- 审计云基础设施:检查AWS和GCP的审计日志,查找未经授权的密钥访问。
- 监控网络活动:阻止与
webhook.site域名的出站连接,并监控防火墙日志。
安全建议
- GitHub安全加固:审查并移除不必要的GitHub应用和OAuth应用,启用分支保护规则,开启GitHub Secret Scanning警报。
- 持续监控:设置警报,监控新的NPM发布,定期轮换凭证,使用有限范围的令牌进行CI/CD管道操作。
此次攻击展示了供应链威胁的复杂性和严重性,开发者和管理员需提高警惕,采取有效措施防范类似攻击。
评论总结
评论内容总结:
NPM供应链攻击的普遍性与原因
- 评论者认为NPM的供应链攻击频繁发生,可能是由于操作复杂性或NPM本身存在根本性问题。
- 引用:"We've seen many reports of supply chain attacks affecting NPM. Are these symptoms of operational complexity, or is there something fundamentally wrong with NPM?"
- 引用:"New day, new npm malware. Sigh.."
解决方案与改进建议
- 一些评论者提出通过OIDC机制、可重复构建、CI系统验证等方式减少攻击风险。
- 引用:"My main takeaway is to stop using tokens, and rely on mechanisms like OIDC to reduce the blast radius of a compromise."
- 引用:"This seems like something that can be solved with reproducible builds and ensuring you only deploy from a CI system that verifies along the way."
对NPM生态的批评与替代方案
- 评论者批评NPM依赖过多,建议使用无依赖的项目(如esbuild)或减少JavaScript的使用。
- 引用:"I knew npm was a train wreck when I first used it years ago and it pulled in literally hundreds of dependencies for a simple app."
- 引用:"These attacks may just be the final push I needed to take server rendering (without js) more seriously."
对NPM管理的建议
- 评论者建议借鉴Debian的包管理方式,通过稳定版和测试版的分发模式进行审核。
- 引用:"The general solution is to do what Debian does. Keep a stable distro where new packages aren’t added and versions change rarely."
对JavaScript生态的反思
- 评论者认为JavaScript缺乏强大的标准库,导致依赖树过于庞大,建议社区创建安全的依赖分发。
- 引用:"I think these kinds of attack would be strongly reduced if js had a strong standard library."
对攻击的技术细节与命名调侃
- 评论者对攻击的技术细节和命名进行了调侃,指出恶意软件的文件大小和命名方式。
- 引用:"Clever name... but I would have expected malware authors to be a bit less obvious. They literally named their giant worm after a giant worm."
- 引用:"Yep, even malware can be bloated. That's in the spirit of NPM I guess..."
总结:评论者普遍对NPM的供应链攻击表示担忧,提出了多种解决方案和改进建议,同时对JavaScript生态的依赖问题进行了反思和批评。