开源生态系统持续面临有组织、自适应的供应链威胁,这些威胁通过被泄露的凭证和恶意的软件包生命周期脚本传播。最近的典型案例是多波次的Shai-Hulud攻击活动。 虽然具体事件在攻击手法和速度上各有不同,但模式是一致的:攻击者学习迅速,针对维护者的工作流程,并利用发布管道中的信任边界。 本文提炼了具有持久性的经验教训和行动建议,以帮助维护者和组织加固其系统,为下一次攻击活动做好准备,而不仅仅是应对上一次。我们还将分享接下来两个季度npm安全路线图的更多内容。
近期Shai-Hulud攻击活动
Shai-Hulud是一个针对JavaScript供应链的协同、多波次攻击活动,已从机会主义入侵演变为有计划的针对性攻击。
第一波攻击侧重于滥用被泄露的维护者账户。它通过注入恶意的post-install脚本来将恶意代码植入软件包,窃取密钥并进行自我复制,展示了单个立足点如何能迅速波及依赖链。
被称为Shai-Hulud 2.0的第二波攻击升级了威胁:其自我复制和通过泄露凭证传播的能力得到更新,能够实现跨受害者的凭证暴露。第二波攻击还通过自托管运行器注册引入了端点命令与控制,窃取更广泛的密钥以推动进一步传播,并具有破坏性功能。此波攻击增加了对CI环境的关注,当其检测到在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依赖项,启用代码扫描,并且别忘了解决代码扫描警报!
- 监控软件包制品,并根据源代码验证已发布的tarball/捆绑包(例如,使用子资源完整性或制品构建证明)。
请注意,上述建议是预防性的。如果您认为自己受到攻击并需要帮助保护您的GitHub或npm账户,请联系GitHub支持。
参考文献
- 在npm中报告恶意软件包
- 我们为更安全的npm供应链制定的计划
- 加强npm安全
- 在安全通告数据库中查看恶意软件通告
- 保护仓库的快速入门指南
- GitHub上的依赖项审查
- 针对npm的OpenSSF最佳实践
- 微软的检测和防御指南
- GitHub Actions的最新改进