加强供应链安全:为下一场恶意软件攻击活动做好准备
为帮助减少下一次供应链恶意软件攻击的影响,面向用户和维护者的安全建议。
开源生态系统持续面临有组织、自适应的供应链威胁,这些威胁通过泄露的凭证和恶意的包生命周期脚本传播。最近的例子是多波次的Shai-Hulud攻击活动。
虽然具体事件在机制和速度上有所不同,但模式是一致的:攻击者学习迅速,针对维护者的工作流程,并利用发布流水线中的信任边界。
本文提炼了持久的经验教训和行动方案,以帮助维护者和组织加固其系统,为下一场攻击活动做好准备,而不仅仅是对上一场做出反应。我们还分享未来两个季度npm安全路线图的更多内容。
近期Shai-Hulud攻击活动
Shai-Hulud是一项针对JavaScript供应链的协调、多波次攻击活动,已从机会主义入侵演变为工程化、有针对性的攻击。
第一波主要滥用被入侵的维护者账户。它注入恶意的post-install脚本,将恶意代码植入软件包,泄露密钥并进行自我复制,展示了单次入侵如何迅速波及依赖项。
第二波,即Shai-Hulud 2.0,将威胁升级:其自我复制和通过泄露凭证传播的能力得到更新,能够实现跨受害者凭证泄露。第二波还通过自托管运行器注册引入了端点命令与控制,收集更广泛的密钥以推动进一步传播,并增加了破坏性功能。这一波还重点关注CI环境,当其检测到在此环境下运行时改变行为,并包含针对特定构建代理的权限提升技术。它还使用了比前一波载荷更难检测的多阶段载荷。变种之间时间间隔的缩短表明存在一个有组织的攻击者,他们在研究社区的防御措施并迅速迭代绕过。
Shai-Hulud攻击活动并非孤立的入侵,而是针对维护者工作流程和CI发布流水线中的信任边界,重点关注凭证收集和安装时执行。我们在各波攻击中看到的特征包括:
- 凭证相关的入侵:攻击者通过泄露的凭证或OAuth令牌获得初始立足点,然后转向收集更多密钥(npm令牌、CI令牌、云凭证)以扩大影响范围。这使得攻击可以在组织间重复利用,并在未来的攻击波中无需单一故障点。
- 带混淆的安装时执行:恶意的post-install或生命周期脚本被注入软件包(或依赖链),仅在运行时才显露行为。载荷通常根据条件激活(例如环境检查、组织范围),并使用针对其运行环境的技术来窃取数据。
- 针对受信任的命名空间和内部包名:该活动影响了流行且受信任的包,并且蠕虫发布了使用现有包名的受感染包。第二波还修补了包的版本号,使受感染的包看起来像合法的更新,混入正常的维护者活动中。
- 快速迭代和围绕防御进行工程化:变种之间的短时间间隔和旨在绕过先前缓解措施的刻意更改,表明了其有组织的攻击活动思维。目标是持久的访问和可扩展的传播,而非一次性的机会主义行为。
- 审查发布流水线中的盲点:源代码与已发布构件之间的差异、生命周期脚本以及构建时转换,造成了如果团队缺乏构件验证或阶段性审批,注入的行为就可能在不被注意的情况下植入的缺口。
此模式中的近期攻击波强化了防御者应主动加固发布模式和凭证流,而不是为任何单一变种定制缓解措施的观点。
npm的未来计划
我们正在加速我们的安全路线图,以应对不断变化的威胁环境。展望未来,我们的近期重点是增加对以下功能的支持:
- 批量OIDC接入:简化的工具,帮助组织大规模地将数百个包迁移到可信发布。
- 扩展的OIDC提供商支持:增加对GitHub Actions和GitLab以外的其他CI提供商的支持。
- 阶段性发布:一种新的发布模型,在包上线前为维护者提供审查期,需要包所有者通过MFA验证批准。这使团队能够在更改到达下游用户之前发现意外变更——这是社区多年来一直要求的功能。
这些投资共同为维护者提供了更强大、更灵活的工具,以在发布过程的每个阶段保护其软件包。
给GitHub和npm用户及维护者的建议
像Shai-Hulud这样的恶意软件通常通过向npm包添加恶意代码来传播。恶意代码作为包安装的一部分执行,因此任何安装该包的npm用户都会受到入侵。恶意软件会搜索本地系统以寻找令牌,然后利用这些令牌继续传播。由于npm包通常有许多依赖项,攻击者只需将恶意软件添加到一个包中,就可以间接感染许多其他包。并且通过囤积部分窃取的令牌而不是立即使用,攻击者可以在初始入侵数周或数月后发起新的攻击活动。
在下面的“参考资料”部分,我们包含了分析近期攻击活动以及如何保持安全的长篇文章链接,因此我们不会在此重复所有信息。相反,这里是我们最重要建议的简短总结:
给所有人的建议
- 在所有账户上启用防网络钓鱼的多因素认证,特别是GitHub包管理器(如npm、PyPI、RubyGems或NuGet)的账户,以及任何可能被用于账户接管或网络钓鱼的账户,如电子邮件和社交媒体账户。
- 始终为令牌设置过期日期,以确保其按计划定期轮换。组织可以强制执行最长生命周期策略。
- 审计并撤销未使用的GitHub/OAuth应用程序的访问权限。
- 在沙箱(例如GitHub Codespaces、虚拟机或容器)中进行开发工作。这可以限制您意外运行的任何恶意软件的访问权限。
给维护者的建议
- 启用分支保护,这样即使攻击者拥有有效的令牌,也无法直接将恶意更新推送到您的主分支。
- 使用npm可信发布,而不是令牌。可信发布也可用于其他包管理器,如PyPI、RubyGems和NuGet。
- 固定CI依赖项,启用代码扫描,并且别忘了处理代码扫描警报!
- 监控包构件,并根据源代码(例如SRI或构件构建证明)验证发布的tarball/捆绑包。
请注意,上述建议是预防性的。如果您认为自己遭受了攻击并需要帮助保护您的GitHub或npm账户,请联系GitHub支持。
参考资料
- 在npm中报告恶意包
- 我们关于构建更安全的npm供应链的计划
- 加强npm安全性
- 在安全公告数据库中查看恶意软件公告
- 保护仓库的快速入门
- GitHub上的依赖项审查
- OpenSSF针对npm的最佳实践
- 微软的检测和防御指南
- GitHub Actions的近期改进