一、序言

开源软件已经渗透到信息技术领域的方方面面,无论是CPU、DSP等芯片,抑或驱动、固件等底层软件,抑或操作系统、浏览器、数据库等系统软件,抑或消息中间件、应用服务器等中间件软件,抑或各种各样的应用软件,都有开源软件的应用。我国信息技术领域各个行业也大量使用了开源软件。对于政府、军工、能源、金融等关键行业,也从以前的“谈开源软件色变”,到现在已经广泛接受和应用开源软件。开源软件已经成为当前软件供应链中十分重要的组成部分。

开源软件为IT行业带来了极大便利,提高了开发效率,降低了成本。然而,由于开源软件的依赖和引用关系较为复杂,其安全性也往往缺少审查和管理,因此,开源软件也增加了软件供应链的复杂性和安全风险。2019年,Github的报告指出,超过360万个开源项目依赖了Top50的开源项目之一。rails/rails、facebook/jest、axios/axios等知名项目被其他上百万个开源项目使用。同时,开源项目平均有180个第三方依赖组件,具体的依赖组件数量从几个到上千个不等。另一方面,NVD、CNVD等漏洞库中的开源软件漏洞数量不断增加,还有大量开源软件漏洞未被收录到这些漏洞库中,例如,被广泛使用的fastjson组件,在2019年持续出现的严重漏洞中,多个漏洞尚未收录到国家漏洞库中。恶意软件包也不断出现在开源社区中,如pip包管理平台的roels、req-tools和dark-magic等恶意软件包、NPM包管理器的m-backdoor、rceat、path-to-regxep等恶意软件包等。

除了信息安全风险,开源软件还可能引入知识产权风险。由于开源软件的依赖关系的复杂性,在使用开源软件时,不同开源软件的许可证可能存在合规性和兼容性风险,从而导致知识产权风险。2019年11月6日,数字天堂(北京)网络技术有限公司诉柚子(北京)科技有限公司、柚子(北京)移动技术有限公司侵犯计算机软件著作权纠纷一案终审判决,判令柚子公司停止侵权并赔偿71万元。该案被称为中国第一个涉及GPL协议的诉讼案件。虽然该案在开源社区中有不同的讨论和解读,但进一步说明了开源软件的知识产权风险,是不可忽视的重要风险之一。

由此可见,开源软件复杂的供应链关系、不断增加的安全漏洞与恶意软件包,以及开源许可证的风险,已成为不可忽视、亟需重视和管控的领域。2020年4月27日,国家互联网信息办公室、国家发改委等12个部门联合发布了《网络安全审查办法》,《网络安全审查办法》中第一条明确指出:“为了确保关键信息基础设施供应链安全,维护国家安全,依据《中华人民共和国国家安全法》《中华人民共和国网络安全法》,制定本办法”。开源软件作为关键信息基础设施供应链中十分重要的组成部分,其安全性也需要重点关注。因此,为了更详细地进行分析,我们从Github、码云社区中选取了一批开源项目进行分析,就其依赖组件、安全漏洞、开源许可证等方面进行分析。

二、开源软件的安全风险分析

本报告一共选取了48363个项目进行分析,其中GitHub中选取星数为500星及以上的开源项目38530个,Gitee中选取星数为5星及以上的开源项目9833个。进一步,使用开源安全检测工具对48363个开源项目进行依赖检测,检测是否含有来自于Maven、Nuget、Packagist、PyPI、NPM、RubyGems六个包管理平台的依赖组件。在检测结果中,共有31553个开源项目包含上述六个平台的依赖组件,占总数的比例为65.24%。在含有依赖组件的开源项目中,来自于Github社区的项目数为25959个,占比82.27%;来自于Gitee社区的项目数为5594个,占比17.73%。本报告通过对31553个含依赖组件的开源项目(下称“样本项目”)进一步进行分析。

样本项目中一共包含701724个来自Maven、Nuget、Packagist、PyPI、NPM、RubyGems六个平台的依赖组件,其中Github的样本项目包含535326个依赖组件,占比76.29%,Gittee的样本项目包含166398个依赖组件,占比23.71%。通过对样本项目的依赖组件安全性进行分析,共获得依赖组件漏洞警告信息83834条。其中,总样本项目的20.79%存在依赖组件漏洞,按开源社区划分,18.03%的Github样本项目包含依赖组件漏洞,33.63%的Gitee样本项目包含依赖组件漏洞。基于以上数据,本报告从样本项目的依赖组件安全风险、漏洞等级分布、开源许可证等维度进行进一步分析。

(一)组件安全风险分析

(1)组件安全风险宏观分析

1.1. 样本项目的组件漏洞数量①持续增长

组件漏洞数量及其增长态势是宏观上衡量开源安全风险的重要指标,根据以上数据分析可知,开源项目依赖组件漏洞数量逐年增长,近4年中2019年增长最快,2019年组件漏洞数量相较2018年环比增长72.99%。2019年,Github样本项目的依赖组件漏洞数量环比增长71.05%,Gitee样本项目的依赖组件漏洞数量环比增长74.18%。以上表明,组件漏洞数量一直处于较高增长态势,成为开源项目不可忽视的重要漏洞来源之一。

(①注:本报告组件漏洞数量是指开源项目中依赖组件中的漏洞数量。年度组件漏洞数量指截止当年末为止的历史累计组件漏洞总量。漏洞知识库以CVE漏洞为主,也含有部分开源社区漏洞来源,如Github、NPM等。)

1.2. 多数组件漏洞集中于少数包管理器平台

在本次分析的6个主流包管理器Maven、Nuget、Packagist、PyPI、NPM、RubyGems中,Maven组件漏洞数量最多,占比73.54%,Maven组件漏洞数在近4年中每年均远多于其它包管理器,并在近两年中大幅增长,2019年环比增长达到76.53%。NPM位居第二,占比16.11%,但仍与Maven差值巨大。其它包管理器则一直维持在增长较为缓慢、漏洞数较少的水平。总体而言,大多数组件漏洞集中在少数包管理器平台。

1.3.直接依赖漏洞数量比间接依赖漏洞数量少约10%

软件工程中所包含的开源组件按依赖层级分为直接依赖组件与间接依赖组件,软件工程所依赖的第一层级的开源组件被称为直接依赖组件,第一层级以及更深层级开源组件所依赖的开源组件被称为间接依赖组件,直接依赖组件漏洞和间接依赖组件漏洞都是不可忽视的安全风险。依据依赖组件漏洞数量的总体结果分析,直接依赖漏洞的数量为37865个,占比为45.17%,间接依赖的漏洞数量为45969个,占比为54.83%。直接依赖组件的漏洞数量比间接依赖组件的漏洞数量少约10%。同时,由于间接依赖关系需要对组件的依赖关系进行多层次分析,间接依赖组件漏洞相比直接依赖组件漏洞更具隐蔽性。

(2)样本项目组件漏洞危害性分析

2.1. 超半数组件漏洞具有较高危害性

根据安全漏洞的危害程度不同,由美国国家基础设施咨询委员会NIAC(TheNational Infrastructure Advisory Council)发布的通用漏洞评估方法CVSS(CommonVulerability ScoringSystem)将安全漏洞分为超危、高危、中危、低危4个等级的漏洞。根据本报告统计结果,组件漏洞多集中于中危及以上等级,占比94.38%;其中,中危等级的组件漏洞数量最多,占比35.26%,超危与高危组件漏洞数量分别为31.44%和27.67%,低危漏洞较少,占比5.62%。超危与高危组件漏洞数量之和占比达64.49%。总体而言,中危及以上漏洞即已具有一定危害性,而其占比达94.38%,高危及以上漏洞则具有较高危害性,而其占比达64.49%,显而易见,依赖组件的安全漏洞是不可忽视的重要安全风险之一。

2.2.高危及以上组件漏洞数量不断增长,安全风险持续升高

超危、高危组件漏洞数量近年来一直保持着较高的增长率,2017年相较2016年环比增长172.91%,2018年环比增长108.37%,2019年环比增长103.96%,超危、高危组件漏洞数量历年均保持着大于100%的较高的增长率。Github样本项目和Gitee样本项目的超危与高危漏洞数量也基本符合这一规律。而在实际开发中,组件漏洞被发现后,大量开源组件的漏洞修复周期也较长,不能做到对组件漏洞的及时响应。据英国安全厂商Snyk调研,37%的开源开发者在持续集成(CI)期间没有实施任何类型的安全测试,25%的开发者在发现漏洞后未通知用户有漏洞,从漏洞添加至组件到修复漏洞的时间中位数也超过2年,而超危、高危漏洞的危害性较高且占比较高,若大量开发者未能做到对漏洞的及时响应,将对组件使用者带来较高的安全风险。

2.3.约80%的高危及以上的组件漏洞来自Maven组件

各包管理器每年的超危、高危组件漏洞数量均在不断变化,上表反映了各包管理器每年的超危、高危组件漏洞占超危、高危漏洞总数量的比例的变化情况。尽管Maven平台高危及以上的组件漏洞在2016-2018年期间占比略微下降,但仍旧在每年中均保持最高占比,平均每年占比超80%,并超出位于第二名的NPM至少65%。而除了Maven和NPM外的其它包管理器则一直处于占比较低的状态。总体而言,历年大部分的高危及以上的组件漏洞来自于Maven组件,也侧面说明了Maven组件使用范围较广,Maven组件漏洞的影响范围也相应较广。

2.4.被引用次数最多的含高危及以上漏洞的组件Top10

开源组件被引用的次数越多,软件开发者直接或间接依赖到该组件的可能性越大,如果该组件包含高危及以上漏洞,安全风险越高,安全风险影响范围也越广。了解各包管理器中被引用最多的高危组件信息,对于开源安全风险防范至关重要。本报告从样本项目依赖组件中按包管理器分别选取了被样本项目引用次数最多的且包含高危及以上漏洞的组件Top10,其中,图中横坐标表示该组件被样本项目引用的次数:

  1. Maven

  1. Nuget

  1. Packagist

  1. PyPI

  1. NPM

  1. RubyGems

(二)开源许可证分析

本报告对样本开源项目与依赖组件(来自于Maven、Nuget、Packagist、PyPI、NPM、RubyGems这6个包管理平台的依赖组件)的许可证使用情况进行了统计,无论是开源项目还是依赖组件,MITApache-2.0许可证占比最多。依赖组件许可证中,MIT占比55.58%,Apache-2.0占比14.94%;开源项目许可证中,MIT占比32.93%,Apache-2.0占比14.84%;AGPL-3.0、LGPL-2.1、LGPL-3.0、GPL-2.0、GPL-3.0占比最少,5个许可证占比之和不足10%。依赖组件中,未在社区网页申明许可证的占比仅为2.88%,而在开源项目中,未在社区网页直接申明许可证的占比为39.44%。当然,开源项目许可证存在一种情况,即未在社区网页直接申明,而将许可证声明放到源代码项目中。因此,实际未申明许可证的开源项目比例会略低于39.44%,但侧面反映了开源项目中,未申明许可证的开源项目数量较多。对于未申明许可证的开源项目或开源依赖组件的使用,可能存在侵权风险。

许可证兼容是指不同许可证的开源项目,能在同时不违反所有开源项目许可证的前提下进行合并或者融合,反之则成为许可证不兼容。许可证兼容性风险是使用开源软件时面临的常见风险。开源许可证可以简单划分为宽松型许可证和著佐权型许可证。例如MIT、Apache-2.0、BSD-2-Clause、BSD-3-Clause属于宽松型许可证,AGPL-3.0、LGPL-2.1、LGPL-3.0、GPL-2.0、GPL-3.0属于著佐权型许可证。开源软件或依赖组件在混合使用时,由于不同的开源软件或依赖组件具有不同的开源许可证,因此可能存在许可证兼容性风险。

本次分析中,2372个样本项目存在许可证兼容性问题,占比7.52%。这些项目中,有的使用了许可证不兼容的依赖组件,有的是依赖组件许可证与项目自身的许可证不兼容。例如Mycat-Server项目,其项目许可证为GPL-2.0,项目中使用的依赖组件的许可证有Apache-2.0、GPL-2.0等。但由于Apache-2.0存在某些专利条款和赔偿条款,而GPL-2.0未做相关要求,导致Apache-2.0与GPL-2.0不兼容。因此,当整个项目在GPL-2.0许可证下,整个项目就存在兼容性问题。

三、开源安全风险防范建议

《网络安全审查办法》要求加强关键信息基础设施供应链安全,开源软件作为关键信息基础设施软件供应链中的重要组成部分,其安全性亟需予以重视。因此,开发者应该采取适当的措施进行规避,可有效降低其安全风险。为此,建议开发者采取以下主要措施:

1、在引入开源软件时做好安全审查,避免在开发时就引入含漏洞的开源软件,导致安全风险传递到后续流程;

2、在引入开源软件时做好法律审查,避免引入不符合使用需求的开源许可证项目;

3、获取专业的开源软件安全信息的服务支持,以加强开源漏洞信息的获取能力;

4、做好开源软件清单的管理,以便在获取开源软件威胁情报时,及时发现受影响的产品和项目,快速进行处置;

5、建立开源软件管理制度,加强人员对于开源软件风险意识的培训。

本报告由CNCERT软件安全和苏州棱镜七彩科技有限公司联合发布。

声明:本文来自CNCERT风险评估,版权归作者所有。文章内容仅代表作者独立观点,不代表安全内参立场,转载目的在于传递更多信息。如有侵权,请联系 anquanneican@163.com。