当前位置: 首页 > 科技观察

依赖库劫持漏洞已经影响了谷歌GitHub等7万多个开源项目的供应链

时间:2023-03-13 16:27:27 科技观察

研究人员最近发现依赖库劫持非常普遍。这是一个隐藏的漏洞,允许任何人更改用户劫持没有名称的存储库。与子域接管类似,该漏洞容易被利用并导致远程代码注入。研究人员分析了存在该漏洞的开源项目并总结了依赖关系图进行搜索后,发现受影响的开源项目超过70,000个,其中包括来自Google、GitHub、Facebook等公司的热门项目和框架。要缓解此漏洞,请确保您的项目不依赖于GitHub的直接URL或使用依赖项锁定文件和版本固定。什么是回购劫持?依赖库劫持(又名“RepoJacking”)是供应链中一个鲜为人知的漏洞,概念上类似于子域接管,影响超过70,000个开源项目,影响从Web框架到所有使用加密货币的操作。该漏洞不易被利用,可导致远程代码注入,并影响谷歌、GitHub、Facebook、Kubernetes、NodeJS、亚马逊等公司的重大项目。在最近的一次活动中首次发现该漏洞后,研究人员想知道如何它很常见,因此他们对所有开源项目进行了递归分析,发现它非常普遍。哪些对象容易受到RepoJacking攻击?每个编译依赖GitHub存储库的动态链接代码的项目都可能受到攻击,但要使攻击成功,需要满足两个条件:您的代码需要直接引用GitHub存储库(通常作为依赖项)。存储库的所有者需要更改/删除他们的用户名。当链接的存储库所有者更改其用户名时,任何人都可以立即重新注册该用户名。这意味着任何链接回原始存储库URL的项目现在都容易受到依赖劫持远程代码注入的攻击。恶意攻击者可以注册一个旧的GitHub用户名,重新创建存储库,并使用它为任何依赖它的项目提供恶意代码。即使依赖GitHub存储库的项目现在不易受到攻击,但如果其中一个依赖项的所有者更改了他们的用户名,那么该项目和依赖于该旧链接的其他项目就容易受到repojacking的攻击。当存储库更改位置时,可能会有某种警告,例如“404-未找到存储库”之类的,但实际上并没有。此外,Github的一个小功能(存储库重定向)使该漏洞更加危险。“存储库重定向”使攻击变得更糟当GitHub用户更改存储库的名称或用户名时,GitHub会设置从旧URL到新URL的重定向,这适用于HTTP和Git请求。当用户更改用户名、转移存储库或重命名存储库时,将创建此重定向。这里的错误是,如果您重新创建原始存储库(在本例中为“twitter/bootstrap”),重定向将中断并将您发送到新创建的存储库。示例场景链接https://github.com/twitter/bootstrap指向存储库“twitter/bootstrap”,但实际上会将您重定向到“twbs/bootstrap”存储库。如果Twitter更改了他们的GitHub用户名,任何人都可以重新注册它,重新创建一个名为“bootstrap”的存储库,任何对https://github.com/twitter/bootstrap的新请求都将进入新创建的存储库。任何依赖https://github.com/twitter/bootstrap的项目现在都将开始从这个新存储库加载代码。重定向是一项方便的功能,因为它意味着当您重命名帐户时链接不会立即中断。但这也意味着您的项目可能会在不知不觉中变得容易受到RepoJacking的攻击。从你的角度来看,什么都没有改变,你的代码编译仍然是一样的,一切都按照它应该的方式工作。但是,您的项目现在容易受到远程代码注入的攻击,而您并不知道。三种劫持场景更具体地说,从技术上讲,存储库可以通过三种不同的方式变得可劫持:GitHub用户重命名他们的帐户。这是存储库被劫持的最常见方式,因为用户重命名他们的帐户并不少见,并且在用户重命名他们的帐户后,由于存储库重定向,一切都按预期进行。Github用户将他们的存储库转移到另一个用户或组织,然后删除他们的帐户。当用户转移存储库时,将建立重定向,打开它以被任何人通过删除他们的用户来劫持。用户删除他的帐户。这是三者中影响最小的,因为从原始用户删除帐户的那一刻起,任何引用该帐户的项目在尝试获取存储库时都会开始出现漏洞。注意:在删除帐户的用户和试图获取存储库的项目之间,有几次攻击者重新注册了已删除的用户名,更多详细信息请参见此处。GitHub回应在发布本文之前,研究人员联系了GitHub,并表示虽然这是一个已知漏洞,但他们目前没有计划改变重定向或用户名的重用方式。他们只是通过禁止重新注册导致在一周内删除具有100多个新复制的存储库名称来为一些流行的存储库提供一些缓解措施,如下所述。这确实提供了一定程度的保护,但不是万无一失的解决方案,因为许多较小的存储库不符合此标准,但仍然可以被流行项目所依赖。这里的根本漏洞不是GitHub允许重定向和用户名重用,而是开发人员从不安全的位置提取代码。GitHub无法监管将其服务用于非预期目的的开发人员。有许多可用的包管理器(事实上,GitHub本身就有一个)可用于解决远程代码依赖漏洞,开发人员有责任确保他们从安全位置加载代码。漏洞范围事实证明,漏洞范围并不容易筛选所有开源项目,编译它们的依赖项,找到所有可以被劫持的存储库,并构建易受攻击存储库的依赖图。第1步:数据收集对开源软件进行大规模分析最困难的部分之一是初始数据收集。很难找到所有开源项目的最新、准确且易于搜索的索引。研究人员主要使用了两个数据集进行分析:(1)GitHubActivityData这是一个由Github自己提供的庞大数据集,包括超过280万个存储库,以及它们的所有文件和内容,整个数据集的内容超过3TB。方便的是,它作为公共BigQuery数据集托管在GoogleCloudPlatform(GCP)上,这意味着研究人员可以使用BigQuery从GCP内部对整个数据集运行SQL命令,而无需下载整个3TB文件。为了实际执行搜索,研究人员生成了一个正则表达式,可以捕获任何GithubURL或其他常见的Github依赖链接格式,例如Github:username/reponame。使用这个正则表达式,研究人员能够提取每个包含对GitHub链接的引用的文件的存储库、文件名和文件内容。这将研究人员的搜索空间从3TB缩小到更易于管理的4GB。过滤后的数据集包括400万个唯一的GitHub链接和超过700,000个唯一的GitHub用户。(2)libraries.iolibraries.io是一个开源项目,旨在将来自多个不同打包程序管理器的所有依赖项聚合到一个类似图形的数据集中。这是惊人的,因为它不仅为研究人员完成了连接依赖于什么的所有繁重工作,而且还使整个数据集可供免费下载。该数据集未压缩时超过100GB,但可以直接加载到数据库中以便于处理。对于研究人员来说,使用这两个数据集很重要,因为每个数据集擅长不同的事情。“Github活动数据”数据集允许研究人员找到存储库中引用的每个可能的Github链接,即使它没有在明显的地方使用,比如在包管理器清单中。一些最有趣的发现不一定是直接的代码依赖,研究人员经常发现在bash脚本中直接使用Githuburl来复制存储库或docker镜像,这些镜像会在构建时从Github拉取存储库。示例安装脚本;任何人都可以注册到GitHub的链接另一个常见的发现是可劫持存储库作为Git子模块,这是标准依赖性分析可能会遗漏的东西。另一方面,“libraries.io”数据集是经过清理、过滤和格式化的数据集,这使我们能够构建依赖图并轻松评估此漏洞的范围。通过这些数据集,我们可以更全面地了解此漏洞对开源项目的整体影响。第2步:清理在收集完所有这些数据后,研究人员需要对其进行清理和规范化,这是一项相当艰巨的任务,因为研究人员需要考虑到每个包管理器的不同格式。此外,研究人员希望删除所有实际上未用作依赖项的链接。其中许多链接用于注释,例如//codeinspiredfromgithub.com/username/reponame,或用于文档文本文件。由于研究人员主要关注代码注入的可能性,因此研究人员删除了代码不会直接使用的任何内容。这给研究人员留下了超过200万个独特的GitHub链接,这些链接被文档以有意义的方式引用。第3步:可劫持的用户名现在我们有了一个直接依赖GitHub链接的项目的清晰列表,我们需要找到当前未注册的用户。到目前为止,研究人员有大约65万个Github用户名需要整理。使用GitHubAPI,研究人员可以检查用户名是否存在,但研究人员被限制在每小时5,000次请求,这意味着检查所有用户名需要5天以上的时间。借助一些巧妙的逻辑和GitHubGraphQLAPI,研究人员能够将扫描所有65万用户的时间缩短到2小时多一点。那么,结果如何呢?研究人员发现,研究人员收集的用户名中有7%(约50k)未注册。老实说,研究人员没想到这个数字会这么高。研究人员认为,只有不到1%的用户名可以被劫持。显然,人们对用户名的厌倦程度超出了预期。第4步:易受攻击的项目一旦研究人员拥有所有可能被劫持的用户名,漏洞利用只是对研究人员的数据集进行反向搜索,每个项目都依赖于用户名拥有的存储库。在进一步过滤和清理误报后,研究人员共发现了18,000个直接容易受到库劫持的项目。这些项目在GitHub上总共拥有超过50万颗星,并且包括来自一些最大的开源组织的几乎所有语言的项目。这个数字本身就很可怕,但现代代码库并不是在单个存储库中运行的单体。相反,它们在功能上依赖于许多其他项目。这对于可维护性和可重用性非常有用,但这意味着单个流行依赖项中的错误可能会极大地影响依赖项链上的许多项目。事实上,任何依赖于18,000个直接易受攻击项目的项目本身都是易受攻击的。第5步:依赖分析现在研究人员有一个直接易受攻击的项目列表,将其与之前的数据集一起使用以执行依赖图污点搜索并找到其供应链中易受攻击的项目仓库中的每个依赖项。在此分析中,研究人员包括了常见的依赖项以及不太明显的依赖项,例如开发依赖项或不在主包清单文件中的依赖项。如果这些辅助依赖项中的一个容易受到reposniping的影响,则这种影响可能需要更长的时间才能传播到依赖项链中,因为这种影响可能仅在开发人员发布新版本时才会发生。考虑到这一点,研究人员开始了他们的攻击分析。由于易受攻击的项目数量呈指数级增长,因此研究人员迭代缓慢。在每次通过期间,研究人员手动审查结果并删除任何明显的误报,以最大限度地减少漏洞的传播,并确保研究人员的结果不会被误报所掩盖。遍历5次后,研究人员不得不停下来。因为在第5轮之前,数据的增长是可以预见的,每一轮搜索都花费了合理的时间,但是当研究人员进行第6轮遍历时,数据开始不受控制地增长。查看第5轮的结果,研究人员构建了多个大型基础框架的原因就很清楚了,这些框架被数千个其他项目所依赖。这足以让研究人员了解漏洞的影响。截至目前,研究人员已发现超过7万个受影响的项目,其中GitHubstar项目总数超过150万个,超过前8名GitHub仓库的总和。虽然很难精确测量,但研究人员估计这些程序的总下载量至少为200万次。受影响的项目包括来自大型组织的存储库,例如Google、GitHub、Facebook、Kubernetes、NodeJS、Amazon等。从小型个人用户项目到数千个组织使用的流行Web框架,一切都受到影响。有趣的是,它会影响许多不同类型的软件。研究人员发现了易受攻击的路由器固件、游戏、加密钱包、移动应用程序和许多其他独特物品。缓解措施不要直接链接到GitHub存储库。版本固定和锁定文件。本文翻译自:https://blog.securityinnovation.com/repo-jacking-exploiting-the-dependency-supply-chain