软件供应链是一个错综复杂的生态系统,即使是单个漏洞也可能引发大范围的安全问题。本文重点关注供应链账户接管问题,特别是NPM包中的安全隐患,深入分析攻击者如何利用过期的电子邮件域名和泄露的凭据来获取访问权限。通过实际案例研究,我们揭示了这类风险的规模及其对相互关联项目的潜在影响。文章还详细介绍了识别和解决这些漏洞的手动和自动化方法。此外,我们还分享了一次全球扫描的发现,突出说明了这一问题的严重性以及采取预防措施的必要性。读完本文后,你将掌握切实可行的策略来保护你的依赖项,降低账户被接管的风险。
什么是软件供应链?
软件供应链涵盖了从编码到生产环境的所有环节,包括依赖项、二进制文件、库文件和其他组件。它是一个相互关联的过程,涉及软件的设计、开发和分发,其中每个环节都至关重要。
软件供应链通过整合各种组件和流程来运作。开发者使用开源库、第三方工具和依赖项来构建应用程序,然后进行测试和部署。从编写代码到部署生产环境的每个步骤,都涉及多个参与者和系统。
就像实体供应链一样,任何一个环节的漏洞都可能蔓延并影响整个系统。随着组织越来越依赖外部资源,确保供应链的安全变得比以往任何时候都更加重要。保护供应链的每个环节,才能确保软件及其最终用户的质量和安全。
什么是NPMjs
NPMjs是一个广受欢迎的包管理器,它让JavaScript库和依赖项的管理变得简单直接。它提供了海量的开源包,开发者可以用这些包来构建和增强他们的项目。使用NPM,你可以轻松地安装、更新和管理依赖项。它还能追踪不同版本,避免兼容性问题。通过简单的命令行工具,你可以运行脚本、发布自己的包,并顺利处理项目设置。NPM已成为现代JavaScript开发中不可或缺的工具,为开发者节省了大量时间和精力。
NPMjs包
NPM包和大多数库一样,常常依赖其他包来实现功能,形成了一条依赖链。这意味着一个包依赖另一个包,而后者又依赖其他包,构成了一个相互关联的网络。如果其中一个依赖项出现问题,就可能影响链条上的许多其他包,造成广泛的问题。在这个生态系统中,理解以下关键术语至关重要:
-
包: 用于执行特定任务的代码、模块或工具的集合。 -
维护者: 负责管理和更新包的个人或团队。 -
依赖方: 依赖特定包的其他包或项目。
下面是一个Express包及其相关统计数据的示例,展示了这个依赖网络的互联性:
问题陈述
我们现在已经了解到,NPMjs是一个注册中心,维护者通过与电子邮件关联的账户来管理包。这些账户对于发布、更新和维护各种项目中使用的包至关重要。但是,如果维护者的账户被攻破会发生什么?
我们需要考虑两种常见情况:
-
邮箱接管: 如果与账户关联的电子邮件地址容易被接管,攻击者就可能控制该账户。 -
凭据泄露: 如果维护者的密码在数据泄露中被暴露且未更新,攻击者可能利用它访问账户。
这两种情况都构成重大风险,因为攻击者可能篡改包,注入恶意代码,从而影响所有依赖该包的项目。
NPM包由维护者管理和修改,他们的账户与电子邮件地址绑定。如果电子邮件地址的域名过期(例如 [email protected]),攻击者可以购买该域名,重新创建邮箱,从而获得维护者账户的访问权限。这使攻击者能够推送恶意更新,影响无数依赖该包的项目。
2022年,一位安全专家为了突出这个问题,接管了一个每周下载量600万次的NPM库的电子邮件域名。详情可阅读:"安全专家接管NPM库邮箱域名以证明问题"(https://www.theregister.com/2022/05/10/security_npm_email/
)。
当时还没有公开的方法来测试这种漏洞,这让许多组织处于风险之中。为了解决这个问题,我们的负责人提出了一个简单的手动方法,这个方法在The Register上的博客中得到了介绍:"NPM依赖项存在漏洞"。这个解决方案为每个人提供了一种可行的方式来识别供应链中的潜在风险。
手动方法包括以下步骤:
-
列出你公司使用的所有包,或参考代码库中已整理好的清单 -
对每个包,使用NPM CLI命令获取维护者邮箱地址: npm view packagename maintainers.email
-
复制包含电子邮件地址的输出内容 -
提取并分离电子邮件地址,创建域名列表 -
对所有域名运行Whois查询,检查是否有过期的域名 -
使用第三方工具(如批量邮件识别器或验证器)进行进一步验证
虽然这种方法在当时解决了问题,但对于管理大量依赖项的组织来说,这既不高效也不具备可扩展性。
自动化方法
对于管理着数百个包的组织来说,依赖手动方法是不切实际的。同时,定期重复这个过程以确保持续的安全性也很重要。为了应对这个挑战,我们创建了一个自动化方法,它甚至可以集成到定时任务中,帮助组织持续防范这种攻击方式。
基于这些考虑,我们在会议上分享了这个脚本,并将其开源供所有人使用。你可以在这里找到它:npm-account-hijacking-scanner(https://github.com/Laburity/npm-account-hijacking-scanner
)。
使用该脚本的方法:
-
测试单个包,使用以下命令: bash npm-account-hijacking.sh -p package_name_here
-
要扫描整个包列表,先将包名编写到文件中(如packages.txt),然后运行: bash npm-account-hijacking.sh -f packages.txt
-
这个自动化解决方案简化了整个流程,并且可以轻松扩展,确保你的供应链安全。
针对此漏洞的全球范围扫描
为了提高安全意识,我们决定通过扫描当时所有可用的NPM包来探究这个漏洞的广泛程度。
这项研究的目标是评估这些包的整体安全状况,特别是针对账户接管的可能性。
在这次全球扫描中,我们从公开渠道收集包信息。通过定制和优化的脚本,结合高性能RAM服务器和专用资源,我们进行了全面分析,以揭示生态系统中的风险和漏洞。
操作方法
第一阶段:收集所有包
第一步是收集互联网上所有可用的npm包。当时,npm仓库中大约有210万个包(准确地说是2,118,539个),可以通过npmjs.com访问。这是一个庞大的数据集,但通过合适的设置,我们成功收集了这些包,为研究奠定了完整的基础。
第二阶段:收集与包关联的邮箱
在完成npm包的完整收集后,我们进入第二阶段,重点收集与每个包相关联的电子邮件地址。这些邮箱属于包的维护者或贡献者,可以帮助追踪包的所有权或责任方。收集这些信息至关重要,因为我们后续会用这些邮箱来评估过期域名和包相关的潜在安全风险。
这个阶段特别具有挑战性,因为我们需要从数百万个包的元数据中提取电子邮件地址。为了处理这个问题,我们部署了10个云实例,每个实例都配置为从包中获取、处理并将邮箱存储到中央存储系统中。这使我们能够在不影响速度和组织性的情况下管理大量数据。最终结果是一个统一的数据库,包含了我们扫描的每个npm包相关的邮箱,为进一步分析做好准备。
在我们的研究设置中,我们使用了最多10个云实例,每个实例配备16GB内存,这提供了高效处理大规模扫描所需的性能。这个基础设施非常适合支持跨数百万npm包的大规模数据提取、排序和域名分析。通过这种配置,我们可以并行运行复杂操作,确保速度和可靠性,同时不影响研究的全面性。这个强大的设置使我们能够快速收集、处理和分析大规模数据,为我们深入了解npm生态系统中的潜在漏洞提供了宝贵见解。
第三阶段:邮箱排序和去重
在收集所有邮箱后,我们进行了详细的分类整理。从npm包中共提取出6,789,211个(超过670万)电子邮件地址,包括重复项。通过仔细筛选,我们将列表精简为603,887个独特的电子邮件地址。这一步确保了我们获得了一个精炼的唯一联系人集合,这对下一阶段的域名过期分析至关重要。
第四阶段:识别过期域名
在这一步中,我们着手检查了与这些独特邮箱地址相关的132,632个域名(来自6,789,211个邮箱地址)的状态。通过WHOIS查询,我们验证了每个域名的过期状态。由于WHOIS查询有严格的速率限制,我们不得不设置并行处理系统并集成API来解决这些限制。那些更新日期已过、可以从在线供应商处购买的域名被标记为过期域名。最终,我们识别出了675个过期域名,这让我们清楚地了解到哪些域名可能被恶意用户接管。
第五阶段:反向分析和脆弱包识别
在最后阶段,我们进行了反向分析以确定存在漏洞的包。我们将与过期域名相关的邮箱地址与第二阶段收集的原始邮箱列表进行交叉对比。这种比对帮助我们识别出可能容易遭受NPMjs包接管漏洞的包。我们发现2,843个npm包与过期域名相关联,这表明它们容易遭受潜在的接管或利用。
研究意义
我们的研究显示,有2,843个包直接面临账户接管风险。虽然这个数字乍看可能并不令人警惕,但软件供应链的互联性却放大了这个风险。还记得之前提到的依赖网络吗?包与包之间常常相互依赖,一个被攻破的依赖项就可能危及无数项目。
例如,即使你的组织只使用了包X,但如果包X依赖于有漏洞的包Y,你的整个系统都可能因包Y而受到威胁。
为了说明这个问题的重要性,让我们看看这2,843个存在漏洞的包的一些数据:
-
分支数量: 这些包被分叉超过41.3万次,潜在漏洞因此传播到了无数项目中。
意义: 被攻破的分支可能广泛传播恶意代码。 -
依赖仓库: 超过25.7万个仓库直接依赖这些包。
意义: 一个包中的漏洞可能影响数千个仓库,使组织面临风险。 -
依赖包: 9.3万个包依赖这些存在漏洞的包。
意义: 这种连锁反应可能影响使用这些包的整个生态系统。 -
贡献者: 超过5万名贡献者参与了与这些包相关的项目。
意义: 如此庞大的贡献者基数意味着广泛的采用,这放大了任何漏洞的潜在影响。
这项分析突显出主动采取措施的重要性,不仅要保护你直接使用的包,还要保护它们的依赖项,因为即使一个漏洞也可能在整个供应链中产生涟漪效应。
如何防范账户接管和供应链攻击
要防范账户接管和其他供应链威胁,采用动态方法至关重要:
-
在所有地方实施多因素认证,增加额外的保护层。 -
使用我们分享的工具和其他工具扫描你的软件开发生命周期,识别存在漏洞的包。 -
避免盲目信任互联网上的任何代码,始终验证其完整性。 -
使用自动化确保依赖项定期更新。 -
采用零信任架构原则,最小化信任并减少攻击面。 -
验证校验和以确认下载包的完整性。 -
评估第三方供应商和依赖项的安全状况。 -
定期进行并保存第三方风险评估。 -
将代码审查作为流程中的标准部分。 -
在开发生命周期中包含渗透测试以识别漏洞。 -
及时关注安全公告和通知。 -
实施SBOM以维护详细的软件组件、版本和元数据列表。SBOM提供了软件供应链的可视性,有助于有效管理风险。
用于扫描依赖树安全风险的工具
-
GitHub安全警报 -
Dependabot -
GitLab安全扫描 -
npm audit -
Node.js的retire.js -
Ruby的bundler-audit -
Java和.NET的OWASP Dependency-Check -
ShiftLeft和bundler-integrity增强扫描
结论
供应链账户接管在当今软件开发流程中构成重大风险。本文概述了从手动检查到自动化解决方案的实用步骤,这些步骤可以帮助组织超前防范潜在威胁。通过保护依赖项并采用最佳实践,你不仅可以保护自己的代码库,还能保护它影响的更广泛的生态系统。供应链安全关乎维护信任和确保韧性。今天采取主动措施可以避免明天的后果。
原文始发于微信公众号(独眼情报):大规模供应链安全 - 对 NPM 帐户接管的研究
- 左青龙
- 微信扫一扫
-
- 右白虎
- 微信扫一扫
-
评论