本次分享的论文“Investigating Package Related Security Threats in Software Registries”主题是软件供应链安全,关注的是主流开源软件生态里与软件包(Package)相关的各种安全问题。论文由奇安信技术研究院、清华大学、东南大学、中国海洋大学和特拉华大学合作完成,已被国际顶级学术会议IEEE S&P‘23(The 44th IEEE Symposium on Security and Privacy)录用。该项研究工作是奇安信技术研究院“天问”软件供应链安全分析平台相关研究的一部分,奇安信技术研究院也是论文的第一作者单位。

Java、Python等流行的开发语言生态都具有软件源(Package Registry),用于托管可复用的软件包(Package),这些数量众多的软件包已经是现代软件开发中不可缺少的一部分,软件包的分发过程也成为软件供应链安全的薄弱环节。据Sonatype统计,2021年,仅PyPI、npm、Maven和NuGet四个软件源就吸引了2.2万亿次下载;与此同时,针对软件源的软件供应链攻击事件激增650%,造成巨大的安全威胁。

论文从软件包的生命周期出发,梳理了与开源生态相关的主要参与方,如图1所示,包括软件源(Registry)、镜像站(Registry Mirror)和客户端(Registry Client)三类。(1)软件源用于托管软件包,并供用户下载使用。从运行模式看,软件源可分为两类。npm、PyPI、Maven、NuGet、Cargo等均为中心化软件源,这些软件源均维护了一个网站,使得软件包维护者可注册帐号,并在这个网站上发布、更新、删除软件包。与之不同,Go是去中心化的软件源,Go并未维护一个中心式的网站存储软件包,而是让Go的包维护者直接将软件包托管到GitHub、GitLab等代码托管平台,供用户下载。(2)镜像站维护一个与软件源具有相同内容的网站,主要用于加速软件包的下载过程。镜像站可使用Nexus、Artifactory等专业软件源镜像工具提供服务,也可自主研发同步算法进行内容同步。绝大多数软件源均有用户众多的各种镜像站,例如,国内某知名厂商的npm镜像站月下载量超过20亿次。(3)软件包维护者使用客户端发布、维护、管理软件包,软件包用户(通常为软件开发者)同样使用客户端来搜索、下载、安装软件包。

论文详细分析了软件包的整个生命周期,寻找其中可能存在的安全问题。首先,软件包维护者需要在软件源提供的网站上注册新帐号,随后包维护者可通过此帐号进行后续的软件包发布、更新、删除等操作。当新增软件包、发布新版本或者软件包被删除时,镜像站需要及时地同步变更,从而使得镜像站中的内容与软件源中的内容保持一致。软件包用户利用客户端,可通过软件源或者镜像站搜索、下载软件包,并将其集成到自有软件工程中。论文在当前的软件包生态中发现了资源重用资源差异、资源混淆三大类典型问题,并在此基础上识别出12个潜在攻击向量,其中6个为首次发现的攻击向量。论文发现的典型安全问题如下:

资源重用(Reused Resources):软件包名、用户名、URL地址等资源重用在各种系统中普遍存在,不恰当的资源重用是一类典型的安全问题。造成这类问题的原因有多种,包括:(1)部分软件源允许包维护者删除已发布的软件包,并允许新的包维护者任意重用被删除的软件包标识符,攻击者可重用被删除的包标识符,从而对该软件包的已有用户进行攻击(Package Use-After-Free Attack)。(2)软件包维护者帐号的绑定邮箱对应的域名可能已过期,使得攻击者可通过注册域名控制该邮箱,进而通过找回密码等方式取得目标软件包的控制权(Package Maintainer Account Hijacking Attack)。(3)GitHub、GitLab等代码托管平台允许转移项目控制权,并会自动在项目原地址和新地址之间创建跳转(HTTP 301 Moved Permanently),攻击者可通过注册被删除的GitHub帐号打破上述跳转,实现下载劫持(Package Redirection Hijacking Attack),攻击流程如图2所示。

资源差异(Resource Inconsistency): 资源差异可能在软件源和对应的软件镜像站中存在,从而导致一系列安全问题。(1)镜像站应当与软件源提供完全相同的软件包,镜像站中不应该存在额外的软件包。然而,一些镜像站被同时用于发布内部软件包(internal packages),这些软件包在上游软件源中并不存在。攻击者可通过在软件源中发布同名软件包,利用镜像站的同步机制覆盖其内部软件包,从而发起攻击(Mirror Package Override Attack)。(2)当软件源中的软件包被包维护者或软件源管理员删除(大部分为恶意包)时,一些下游镜像站未能同步删除镜像站中对应的软件包,因此会产生大量的幽灵软件包(Ghost Package Attack in Mirrors),持续对镜像站的用户造成威胁。

资源混淆(Confused Resources):不同用户、软件和系统等软件生态相关方对于同一个资源的不同/错误理解,容易导致出现资源混淆问题。例如:(1)一些软件源支持软件包的名称中包含大写字母(例如npm中的 buffer 和 Buffer是两个不同的包),然而,部分镜像站未能正确处理软件包名称中的大小写, 使得无论用户发起的下载请求是大写还是小写(例如,Buffer 或 buffer),镜像站均会返回同一个包(例如,buffer包)。攻击者可利用镜像站的上述缺陷,在软件源中发布名称相同、大小写不同的恶意包,对镜像站的用户发起攻击(Case Sensitivity Confusion Attack)。(2)依赖混淆攻击(Dependency Confusion Attack, DCA)是已知的软件供应链安全问题,攻击者通过在软件源发布与受害公司内部软件包同名但版本更高的恶意包,诱使用户下载安装。论文在已知的virtual repository-side DCA外,重点分析了新型的registry client-side DCA问题及其影响。两种类型的DCA流程如图3所示。(3)Typosquatting是经典的安全问题,也是目前流行的针对软件源的软件供应链攻击手法。论文对主流软件源中的typosquatting情况进行了分析,并讨论了scoped typosuqatting 和 cross-registry typosquatting 两种攻击场景。

为检测上述安全问题并评估其影响,论文设计并实现了RScouter工具,对npm、PyPI、Maven、Go、NuGet、Cargo六大主流开源软件生态进行了为期一年的大规模监测分析,共采集了超过400万个独立软件包,总计5,300万个不同版本。RSouter采集到软件包后,会从中提取包标识符、版本、发布时间、依赖关系、维护者帐号等数据,并对软件包的删除、访问状态改变等事件进行持续监测。随后,RSouter对软件源和对应的镜像站中的数据进行差异分析,识别其中潜在的安全问题。整个监测分析流程如下图所示。

通过大规模监测分析,论文发现6大主流软件源生态均受到多种安全威胁。针对本文提出的部分攻击方式的分析测量结果如下:

  1. Package Use-After-Free Attack. 论文发现PyPI和npm受到此攻击方式的威胁。分析结果如图5所示,可以看到软件包删除事件发生较为频繁:总计超过11万个PyPI软件包和超过6万个npm包被删除。同时,论文发现在24,904个删除后重新发布的PyPI软件包中,有8,283(33.2%)个软件包由不同的包维护者帐号发布;类似地,npm中有229个删除的软件包由不同的帐号重新发布。这些不同账号发布的名字重用的包都具有潜在的安全风险。

  2. Package Maintainer Account Hijacking Attack. 论文发现PyPI、npm、Maven、Cargo、Go等5个生态的软件源受到此攻击方式的威胁。如图6所示,共有16,807个包维护者帐号可被攻击者窃取,影响40,327个软件包。Cargo软件源中受到威胁的帐号比例最低,为0.44%;Go软件源中受到威胁的帐号比例最高,达到4.96%。

  3. Package Redirection Hijacking Attack. Go作为6个软件源中唯一一个去中心化的软件源,受到此攻击方式的威胁。论文分析了托管在GitHub平台上的597,340个Go软件包,发现其中有11,788 (2.0%)个软件包可被攻击:这些软件包存在GitHub自动创建的跳转,并且旧地址对应的GitHub帐号可被攻击者注册。托管在GitLab平台上的8,323个Go软件包中,存在333(4.0%)个软件包可被攻击。图7展示了可被攻击的帐号影响的Go软件包数量,其中有64.4%的帐号只影响一个Go包,6.7%的帐号影响超过5个软件包。由于Go是去中心化的软件源,因此Go官方并未统计每个软件包的下载量。为了说明此攻击方式的实际影响,论文利用七牛云Go Proxy提供的下载统计接口,分析了一个月时间内受影响的Go软件包分别通过新地址和旧地址下载的数量,结果如图8所示,可以看到很多包的旧地址仍然被频繁下载,有一些软件包(例如,github.com/0LuigiCode0/library)甚至全都通过旧地址(github.com/000mrLuigi000/Library)下载。需要说明的是,上述下载量仅通过一个Go proxy统计得来,因此,实际的旧地址下载量可能更高。

  4. Mirror Package Override Attack. 论文发现多个广为使用的镜像站的同步机制存在问题,导致存在大量仅在镜像站中存在的软件包。对于PyPI镜像站,3个镜像站共有84,005个软件包可被攻击者覆盖攻击;对于npm镜像站,2个镜像站共有14,126个软件包可被覆盖攻击。同时,论文还发现某个Maven镜像站允许内部人员上传内部包,这些内部包也可被攻击者覆盖攻击。

  5. Case Sensitivity Confusion Attack. 论文发现npm软件源存在大量的名称中含有大写字母的软件包。虽然npm从2017年开始禁止新发布名称含大写字母的软件包,然而,历史遗留的1,588个含大写字母的软件包仍可被正常使用及发布更新,其中不乏非常流行的包,如objectFitPolyfill包每月下载量超过一百万次。论文发现某个流行的npm镜像站对包名中的大小写的处理存在漏洞——测试表明,不论用户输入的请求是大写字母(例如Buffer)还是小写字母(例如buffer),该镜像站均会返回最近一次更新的软件包(如若buffer是最近更新的,则返回buffer)。上述漏洞会导致严重的安全问题,攻击者可针对含大写字母的正常软件包,向npm软件源上传全小写字母的恶意包,并且保证恶意包比正常包更晚更新,即可对正常软件包的用户发起攻击——即使用户输入了正确的软件包名称,从镜像站下载到的却是攻击者上传的恶意包。

论文将发现的问题反馈至相关的软件源和镜像站,均得到了确认,目前多个问题已经被修复。经过论文的分析可发现,开源生态的软件供应链参与方众多,资源重用、资源不同步、资源混淆等情形时有发生,暴露了多个可被攻击者利用的攻击界面,使得大量软件包面临着潜在安全威胁,其中不乏一些非常流行的软件包。一旦这些处于软件供应链上游的软件包被实际攻击,可能会对下游软件开发商和最终用户产生破坏性影响,值得安全从业人员和软件开发人员的警惕。

论文研究工作是奇安信技术研究院“天问”软件供应链安全分析平台相关研究的一部分,“天问”平台网址:https://tianwen.qianxin.com/