一、开源漏洞发展现状及趋势
根据调查结果,相比2015年漏洞数据,近5年的漏洞数量均有不同程度增长。2018年是开源项目快速增长的一年,根据GitHub官方数据显示,GitHub代码仓库中超过1/3的开源项目创建于2018年,2018年新增开源漏洞数也创下近6年新高,新增7563个漏洞,相较于2015年翻了2.85倍;2017年漏洞增长速度最快,环比增长率为92.86%;2019年与2020年增长率略有下降,2020年发布的漏洞数较2019年发布漏洞数少了1746条。
发现二:CVE官方未收录的开源软件漏洞数逐年递增
对CVE官方网站2进行统计,可发现2020年发布的开源漏洞中未被CVE官方收录漏洞有1362个,占2020年发布漏洞总数的23.78%;CVE官方未收录数据呈上长趋势,增长率逐年递增,2018年环比2017年增长速度达133.52%。
发现三:开源软件漏洞由POC披露到NVD首次公开时间长达11年
2020年发布的开源漏洞中,编号为CVE-2009-4067的Linux内核的Auerswald Linux USB驱动程序的缓冲区溢出漏洞由POC披露到NVD首次公开时间长达11年。POC信息在2009年10月19日披露3;该漏洞于2009年11月24日获得CVE编号,但未公开漏洞具体信息;直到2020年11月2日NVD官方才将其发布。
开源软件的使用者仅关注官方漏洞库(如NVD等)可能无法及时获取漏洞信息,需综合考虑更多渠道的漏洞数据。
发现四:近4年,高危及以上开源漏洞占比均超40%
图4:2020年漏洞危害等级占比
调查结果显示,缺陷类型CWE-79数量最多,占2020年新增开源漏洞的14%左右。表1列出了TOP 10 CWE缺陷类型,这些缺陷类型很容易并被利用,往往通过系统信息暴露、窃取数据或阻止应用程序正常工作等方式,对系统造成安全风险。了解开源漏洞Top10 CWE 可以帮助开发人员、测试人员、用户、项目经理以及安全研究人员深入了解当前最严重的安全漏洞。
CWE编号 | 中文名称 | 个数 |
CWE-79 | 在Web页面生成时对输入的转义处理不恰当(跨站脚本) | 824 |
CWE-506 | 内嵌的恶意代码 | 726 |
CWE-400 | 未加控制的资源消耗(资源穷尽) | 510 |
CWE-200 | 信息暴露 | 305 |
CWE-20 | 输入验证不恰当 | 212 |
CWE-94 | 对生成代码的控制不恰当(代码注入) | 201 |
CWE-119 | 内存缓冲区边界内操作的限制不恰当 | 142 |
CWE-125 | 跨界内存读 | 134 |
CWE-78 | OS命令中使用的特殊元素转义处理不恰当(OS命令注入) | 124 |
CWE-325 | 缺少必要的密码学步骤 | 117 |
二、开源组件生态安全风险分析
发现七:近6年中Maven仓库漏洞数量最多
图7:近6年中各组件仓库漏洞情况
调查结果显示,近6年中漏洞数量最多是Maven仓库,漏洞数量为3533个;Go仓库漏洞数量最少,漏洞数量为348个;平均每个仓库漏洞数量为1413个。
发现八:超半数仓库的漏洞数均较上年有所增长
调查结果显示,近6年,Composer、Go、Maven、npm、PyPI、Rubygems 6种仓库的漏洞数均有不同程度的上涨;Rubygems仓库漏洞增长速度最快,相比去年翻10.5倍;Go仓库和PyPI仓库增长率其次,环比增长率分别为252%和132%;Maven仓库2020年新增漏洞数基本与去年持平。
发现九:2020年高危漏洞占比最高,相比去年增加2.6倍左右
调查结果显示,2020年新增漏洞中,高危漏洞占比最高,数量为1826个;超危漏洞逐年递增,2020年数量有所下降,环比下降53%,2019年新增数量最多,新增数量为468个;高危漏洞逐年递增,2020年增长速度最快,相比去年增加2.62倍;中危漏洞呈现平稳增长趋势,2018年增长速度最快,环比增长率为48.13%;低危漏洞逐年递增,2020年增长速度有所下降,2019年新增数量最多,新增数量为171个。
图9:近6年新增漏洞风险等级时间分布
图10:近6年新增漏洞各风险等级占比
发现十:2020年,含高危以上漏洞占比最多仓库是Rubygems
图11: 2020年各仓库中含高危以上漏洞占比
调查结果显示,超八成组件含高危以上漏洞占比均超过40%。2020年,Rubygems仓库含高危以上漏洞占比最多,占Rubygems仓库新增漏洞的96%;Go仓库含高危以上漏洞占比最少,占2020年Go仓库新增漏洞的39%。
发现十一:平均每版本漏洞最多的TOP 25组件约五成来自Composer仓库
针对2020年各仓库新增漏洞,分析得到平均每版本漏洞数量最多的TOP 25组件。考虑到各仓库不同组件的版本数量各不相同,本报告采取平均每版本漏洞数作为计算依据,即:平均每版本漏洞数=组件全版本漏洞数/组件版本数。
研究发现,平均版本漏洞最多的TOP25中,Composer仓库的组件数占比最多,共计12个,占比约5成左右;PyPI仓库的组件数排名第二,共计7个;平均版本漏洞数最多的组件来自Maven仓库,漏洞数量为47个,下图列示各仓库中平均版本漏洞TOP25 组件分布:
图12:平均版本漏洞最多TOP25 组件仓库分布
图13:Composer仓库组件分布
图14:PyPI仓库组件分布
图15:Maven仓库组件分布
图16: npm和Nuget仓库组件分布
三、组件漏洞依赖层级传播范围分析
软件工程中经常引用组件来实现某些功能,组件之间存在相互依赖关系,按依赖关系可分为直接依赖和间接依赖,即组件A依赖组件B,组件B依赖组件C,那么组件A→组件B和组件B→组件C的依赖关系称为直接依赖,而组件A→组件C的依赖关系称为间接依赖。组件存在安全漏洞,组件之间又存在相互依赖关系,导致漏洞在组件之间存在传播风险。
调查结果显示,原始样本中6,416个组件,受组件依赖关系的影响,一级传播一共波及801,164个组件,其影响范围扩大125倍。第二轮实验中,发现二级传播一共波及1,109,519个组件,影响范围相比原始样本6,416个组件扩大173倍。
发现十三:npm仓库中的组件经2轮传播,影响组件数量最多
调查结果显示,Maven、npm、Rubygems 、PyPI、Composer、Nuget 6个仓库选取样本中,npm仓库原始含漏洞组件数量为1,962个,npm仓库漏洞组件数量在原始样本中仅次于Maven仓库,排在第二位。经2轮模拟传播实验,发现6组仓库中波及范围最广是npm仓库。npm仓库原始样本中共有1,962个含有漏洞的组件,经过一级传播共波及459,876个组件,漏洞的影响范围扩大了234倍;二级传播共波及601,574个组件,范围比最初1,962个组件扩大了307倍。
发现十四:一级传播影响范围最广的仓库是Composer
调查结果显示,Composer仓库原始含漏洞组件数量为380个,为6个仓库中原始样本中含漏洞组件数量的第5位。经1次传播,一级传播波影响范围最广的仓库是Composer。经过一级传播共波及99,611个组件,漏洞的影响范围扩大了262倍。
发现十五:二级传播影响范围最广的仓库是Nuget
调查结果显示,Nuget仓库原始含漏洞组件数量为172个,为6组中含漏洞组件数量最少的仓库。经2次传播,二级传播波影响范围最广的仓库是Nuget。经过一级传播共波及23,240个组件,漏洞的影响范围扩大了135倍;二级传播共波及84,995个组件,范围比最初172个组件扩大了494倍。
发现十六:传播影响范围最小的仓库是Maven
图21: 两轮漏洞传播组件漏洞影响范围分布图
调查结果显示,Maven仓库原始含漏洞组件数量为2,289个,经过2次传播,6组仓库中受漏洞影响范围最小是Maven仓库。经过一级传播共波及94,724个组件,漏洞的影响范围扩大了41倍;二级传播共波及145,827个组件,范围比最初2,289个组件扩大了64倍。
从整体上看,开源组件生态中漏洞影响范围远超预期,组件间的依赖层级关系会导致组件之间漏洞存在传播风险。因此,要保证软件的安全风险控制,应通过自动化的手段识别软件工程中的组件成分,梳理组件间的依赖关系;在已知成分清单基础上对组件漏洞风险实施管控;同时,还要对已知成分进行动态监控,建立组件生态的漏洞威胁警报,在动态变化中将安全漏洞风险降到最低。
四、开源文件潜在漏洞风险传播分析
发现十七:超80%漏洞文件在开源项目具有同源文件
图23: 漏洞文件在开源项目中传播范围分布
通过对含同源文件的14,118个含有漏洞的开源文件进行分析,在不考虑同一开源项目不同版本的前提下,这些漏洞文件被766,877个开源项目所引用,漏洞文件在开源项目中传播范围扩大54倍。如果考虑同一开源项目的不同版本,这些漏洞文件被2,410,476个开源项目所引用,漏洞文件在开源项目中传播范围将扩大171倍。
案例分析
LibTIFF项目中tif_next.c被曝出有2个中危漏洞CVE-2015-1547和CVE-2015-8784。为了解该漏洞文件在开源项目中的引用情况,本研究团队对tif_next.c漏洞文件进行同源分析,在开源项目知识库中共发现有237个开源项目包含tif_next.c文件,如果考虑项目不同版本,共有1000个开源项目中引用tif_next.c文件。表2列出了6大托管平台引用tif_next.c文件的部分同源开源项目,经对比,所有同源文件均仅删减了注释行,而代码逻辑以及函数变量名称均未改变。
托管平台 | 开源项目名称 | 版本号 | 同源文件路径 |
GitHub | reactos/reactos14 | backups/ros-branch-0_4_2@73087 | 见注释15 |
Gitee | mirrors-opencv16 | 2.4.10 | 见注释17 |
Gitlab | limbo18 | v2.2.1-Limbo-armv7-hf | 见注释19 |
Bitbucket | xray20 | FirstAddedTBB | 见注释21 |
Sourceforge | wxhaskell22 | wxInstall-Abriline-32-0.1 | 见注释23 |
CodePlex | casaengine24 | master | 见注释25 |
五、开源安全风险建议
(一)建立开源管理领导组织。随着软件开发过程中开源软件的使用越来越多,开源软件事实上已经成为了软件开发的核心基础设施。开源软件由于其特殊性,从软件供应链视角看,将横跨采购、选型设计、研发编码、运维交付等多个环节,需要跨组织、跨部门协同管理。具备条件的企业、机构建议设立开源管理办公室或领导小组,全面学习开源生态知识,了解开源生态运作机制,开展开源风险意识培训,强化开源风险管控手段。
(二)识别开源成分。开源软件全面渗透至软件供应链体系中,需准确识别软件中的开源成分(包括开源源代码成分、开源二进制成分、引用依赖的开源组件成分等),形成开源成分清单和图谱,做到对软件开源成分的可知可控。同时精确绘制开源组件依赖链条,防止安全风险随着开源组件依赖链条的逐层传播,是进行开源安全风险防范的基础。
(三)修复已知开源漏洞。已知软件的开源成分清单和图谱,明确开源成分及依赖链条后,通过相关工具检测或知识库查询,可有效识别已知开源漏洞。结合项目实际情况进行漏洞修复,降低软件安全风险;对于未修复或短期内无法修复的漏洞,确定安全风险接受清单,明确相关应急响应机制,最大程度降低风险。已知的开源漏洞修复,相较于代码安全审计,往往是将带有漏洞的组件升级至最新或较安全的组件版本,操作简单,易于实施,是一个投入产出比较高的风控措施。
(四)建立开源威胁情报体系。软件安全是动态发展的,开源软件的威胁情报由不同的组织(如开源社区、开源基金会、开源项目方)共同贡献分享。开源威胁情报呈现无统一组织,散落在互联网海量信息中。需建立对已知开源成分及依赖链条漏洞威胁情报的实时监控跟踪机制,搜集多维度多渠道的开源威胁情报,并针对企业、机构已有的开源成分清单和图谱,在第一时间内将有效的开源威胁情报同步给相关责任人。
(五)弃用过老的开源组件和版本,及时安全更新。较老的组件往往存在大量的安全漏洞,也存在软件供应链安全隐患(如停止运维更新升级)。在使用开源软件,应关注其热门程度、受欢迎趋势、社区口碑、更新时效性等因素。应选择较新的安全的开源组件,并做到及时安全更新,降低开源安全风险。
(六)使用左移安全工具。在测试或者交付验收环节,针对开源安全风险进行处置往往会投入更大的工作量和成本。通过使用左移开源安全治理工具的方式,将开源安全风险治理集成到软件开发全生命周期过程中。在需求设计、组件选型、编码集成等早期研发过程中及早发现开源风险问题,从而降低开源安全治理成本。
已完成
数据加载中