第三方组件安全评估指南

第三方组件安全评估指南

组件安全这个话题太大,从去年就一直构思,不知道该怎么写,大半年了,拖延癌晚期,今天终于拼凑了一篇,最近主要在整理组件安全相关方案,感兴趣的童鞋可以给我留言一块交流。


简述

常见第三方组件分为开源和闭源两种情况,广义上的开源组件实际上就是基于各种协议公布源代码让所有人使用的软件依赖,源代码只要遵守对应的协议就可以使用,我们在这里说的开源软件实际上是Open-Source Software的缩写,闭源组件通常由第三方公司提供,方便研发人员实现业务功能而进行统一定制化的,包括依赖库、SDK等等。系统开发中使用的开源外部依赖库如果存在安全风险,会严重威胁系统安全。为全面把控第三方依赖库安全威胁情况,降低外部依赖库带来的安全风险,提高系统整体安全防护能力,应建立相应的第三方组件全生命周期管理体系,对第三方组件进行漏洞检测、修复、报告、跟踪,及时根据官方漏洞修复方案进行漏洞修复。系统上线前,由架构组或者开发组对漏洞检测结果、修复方案、修复结果、未修复原因等信息进行汇总整理,方便后续对第三方组件进行全生命周期管理。
随着时间的推移,第三方组件的安全风险会不断被发现,所以第三方组件生命周期管理是一个持续迭代的过程,建议对第三方组件在引入前、上线前进行安全评估,在系统发版后对第三方组件进行追踪,定期进行安全评估工作。

评估要点

评估要点主要为以下三点:

* 组件安全风险
* 组件合规风险 
* 组件的稳定性 

组件的安全风险

近年来,针对软件供应链的安全攻击事件一直呈快速增长态势,造成的危害越来越严重,防范软件供应链安全风险,已经迫在眉睫;
开源软件漏洞频现:截至2020年底,CVE/NVD、CNNVD、CNVD等公开漏洞库中共收录开源软件相关漏洞41342个,其中高达13%(5366个)为2020年度新增漏洞;
研究发现:近9成软件项目存在已知开源软件漏洞;平均每个软件项目存在66个已知开源软件漏洞;影响最广的开源软件漏洞存在于44.3%的软件项目中;15年前开源软件漏洞仍存在于多个软件项目中。
2020年 “奇安信开源项目检测计划”对1364个开源软件项目的源代码安全检测显示:开源软件项目整体缺陷密度为14.96个/千行,高危缺陷密度为0.95个/千行;

序号 组织类型 缺陷密度(个/千行代码)
1 普通软件工程师 50~250
2 普通软件开发公司 4-40
3 高水平软件开发公司 2~4
4 美国NASA 0.1
5 国内软件公司 6

组件的合规风险

合规风险主要来源于两方面,一方面是开源协议滥用导致的安全风险,另一方面是来之监管合规的风险。

  • 《中华人民共和国网络安全法》第三十三条规定,建设关键信息基础设施应当确保其具有支持业务稳定、持续运行的性能,并保证安全技术措施同步规划、同步建设、同步使用。该条规定,明确了关键信息基础设施的安全工作应该前移,在信息系统的规划阶段就应该保证安全技术措施的介入。
  • 信息安全技术网络安全等级保护基本要求【GBT22239-2019】中要求企业自行软件开发应制定代码编写安全规范,要求开发人员参照规范编写代码,在软件开发过程中对安全性进行测试,在软件安装前对可能存在的恶意代码进行检测;对外包软件开发应在软件交付前检测其中可能存在的恶意代码。
  • 2019年,中国银保监会办公厅文件【银保监办发(2019)129号】文《中国银保监会办公厅关于开展银行业和保险业网络安全专项治理工作的通知》中提出建立新技术引入、开源技术应用安全评估与准入机制,加强科技创新、新技术应用的风险监测与处置。
  • 2020年,中国人民银行办公厅文件【银办发(2020)45号】文《中国人民银行办公厅关于开展金融科技应用风险专项摸排工作的通知》中提出应不定期组织针对开源系统或组件的安全测评,及时进行漏洞修复和加固处理。

对于开源协议不清楚的看官可以直接参考乌克兰程序员Paul Bagwell画的开源协议分析图,介绍最流行的六种开源许可证—-GPL、BSD、MIT、Mozilla、Apache和LGPL。

20201216-01

组件的稳定性

开源社区维护者和贡献者为我们所有人构建工具,为我们日常的开发提供了很大的帮助,但开源社区的贡献者自身却面临诸多问题,这些问题一定程度上影响了开源软件的可持续发展,开源项目的可持续性也一直存在矛盾。这一矛盾导致很多开源软件在最初更新迭代比较快速,文档书写也比较及时,后面却可能出现一些人员离职等问题,导致该开源产品后续的更新不及时,甚至直接中断,这时使用该开源产品的的同学在反馈问题时往往需要很长时间才会得到答复,甚至得不到答复。

  • 除非是非常成熟的开源项目,否则其稳定性是未经考验的,这也是使用开源项目在真正进入持续商业化时所遇到的最大挑战!关于一个项目是否“成熟”,这是个非常主观的问题,如果用Github的star数量来衡量,要充分考虑中国式开源通过运营人头来点赞的模式,即便有1-2万颗星,也并不意味着项目已经成熟了。另外,要看Top-100的贡献者,很多所谓的开源项目几乎所有的贡献者都是项目所在公司的内部员工,这种开源项目的成熟度能有多少呢?
  • 像MySQL,Redis之类这么稳定的项目并不常见,即便是像MongoDB这么宏大的开源项目,一旦进入大规模部署后对于任何中小公司而言都是巨大的挑战,一旦无法克服,会深陷泥潭难以自拔。
  • 国内市场上一度火爆的TFS(Taobao File System=淘宝文件系统),曾经受到很多程序员的追捧,但是很少有人仔细的分析过淘宝的应用场景和对该项目的支持力度,现在该项目已经寿终正寝(淘宝团队不再维护该项目),而且淘宝当时设计的目的是支持海量小文件,而有多少创业项目是一样的业务需求呢?很多人盲目的上马了TFS,到头来发现系统稳定性很差而且有无数的问题,这些是小团队、二次开发能力并不强悍的团队可以承受得了的吗?
    https://zhuanlan.zhihu.com/p/361101335

评估方法

组件评估方法

组件评估方法仅适用于对组件的安全风险进行评估,评估方法如下:

* 使用评估检测工具
* 人工复核排查
* 源代码审计

组件安全检测工具

dependency check

检测人员可使用开源工具Dependency-Check对外部依赖库进行扫描,Dependency-Check是OWASP(Open Web Application Security Project)的一个实用开源程序,用于识别项目依赖项并检查是否存在任何已知的、公开披露的漏洞。Dependency-Check可以命令行形式单独使用,也可集成到各种主流的软件中使用,如Ant、Maven、Gradle、Jenkins、Sonar等。

首先,使用扫描工具Dependency-check对外部依赖库进行扫描,收集整理项目所用外部依赖库,可用Dependency-Check对其进行批量扫描。Dependency-check具体使用方法参见https://jeremylong.github.io/DependencyCheck/dependency-check-cli/arguments.html 。以下将介绍Dependency-Check的命令行使用方式,开发项目组也可将Dependency-Check集成到所使用的软件(如Ant、Maven、Gradle、Jenkins、Sonar等)中使用:

1、进入官网owasp.org/www-project-dependency-check/下载最新版本的Dependency-check,选择Command Line进行下载。下载完成后进行解压即可开始使用。

2、建议每次执行新的扫描任务之前,更新规则库,在命令行窗口进入Dependency-Check的bin目录下,输入更新命令即可完成规则库的更新:

1
dependency-check –updateonly

3、更新完成后,开始进行外部依赖库漏洞的扫描,常用扫描命令如下:

1
Dependency-check --project <project name> --scan <jar path> --out <result path> --format <XML/HTML/CSV/JSON/JUNIT/ALL> --disableCentral

4、打开命令行中的扫描结果存放路径,有多种不同格式的结果,使用“.csv”格式的文件,可方便对扫描结果进行初步整理,保留“DependencyName”、“Md5”、“CVE”、“Vulnerability”、“Severity”等必须项,简化表格,并且在表格中添加与后期修复相关的必须项。

扫描后的结果需人工排除误报,使用工具扫描出来的检测结果存在误报的情况,可能原因包括漏洞与所述组件无关、引发漏洞的方法未被调用、引发漏洞的配置未启用等。需要根据CVE官网上的漏洞介绍、官方漏洞说明结合源代码和修复方法人工进行逐一排查,确认所用组件是否存在扫描结果中所述漏洞,并确定每个漏洞的修复方法,组件安全风险复核是一件相当费时费力的工作。

dependency track

Dependency-Track是一个软件组合分析(SCA)平台,用于跟踪组织创建或使用的所有应用程序中使用的所有第三方组件。它集成了多个漏洞数据库,包括国家漏洞数据库(NVD)、NPM公告、 Sonatype的OSS漏洞库(通过API接口查询)、RiskBased Security的漏洞库。Dependency-Track监控项目中每个应用程序所有版本组件使用情况,以便主动识别整个项目的安全风险。该平台采用API接口设计,非常适合在 CI/CD 环境中集成使用。

20201216-02.jpg

dependency track 具有以下特点:

  • 自动、持续监测依赖安全性
  • 多种类的漏洞数据库
  • 丰富的可视化功能
  • 持续集成友好
  • 可通过多种渠道发送告警
  • AD/LDAP集成
  • 丰富的API

使用其他sbom提取工具,通过接口调用或者直接上传sbom到dependency track,dependency track通过分析sbom,分析组件安全风险,通过仪表盘可以直观追踪安全态势
20201216-03.jpg

使用方法及部署方法较为复杂,后续会单独出一篇文章来详细介绍。

闭源组件

从《个人信息安全规范》新标准的规定可以看出,关于对第三方接入的管理,与共享、转让、委托处理中的规定和责任相似,例如,包括在事前建立第三方产品或服务接入管理机制,在接入后对第三方产品和服务进行持续监督、通过签署合同约束双方责任、需要明确告知个人信息主体服务由第三方提供、对记录进行保存、要求第三方确保个人信息主体授权同意、对第三方接入的自动化工具技术进行技术检测等等。
涉及安全检测,如果提供源代码,可以对源代码进行白盒审计,出于保密考虑,部分单位拒绝提供源代码,可以通过厂商提供的demo,结合接口文档,组件设计文档进行安全评估。

组件安全运营

建议外部依赖库扫描时机为引入前扫描、上线前扫描、定期扫描:

1、引入前扫描:在引入外部依赖库前,对所用版本进行扫描,保证当前使用的外部依赖库版本不存在漏洞,减少后期升级、维护成本。
2、上线前扫描:系统测试阶段或上线前,对系统所使用的外部依赖库进行一次统一扫描,确保上线前外部依赖库不存在公开的高危漏洞。
3、定期扫描:定期对系统使用的外部依赖库进行统一扫描,以全面把控和修复不断暴露出的外部依赖库漏洞。

外部依赖库检测可遵循工具扫描、排除误报、制定修复建议、实施修复的流程进行,形成检测和修复报告,作为开发阶段交付物。
对于线上系统,可以构建组件清单列表,遵循基于组件生命周期的安全解决方案,结合组件威胁情报,一旦某个开源组件出现漏洞,可以通过清单列表迅速排查。以下是基于开源软件生命周期的供应链安全解决方案,供各位参考:

20201216-04.jpg

20201216-05.jpg

修复方法

部分外部依赖包可能存在多个漏洞,需综合各个漏洞,为外部依赖包制定整体的修复方案:问题依赖库对应的各CVE漏洞均有一个修复建议,需根据每个外部依赖包涉及的CVE漏洞的修复方法,考虑到同一依赖包不同漏洞可能存在不同的修复建议,不同依赖包之间可能存在关联依赖关系,建议采用就高不就低原则,综合考虑,形成每个外部依赖包的整体修复建议。
开发团队需根据每个外部依赖包的整体修复建议,采用升级或调整配置等方式,修复外部依赖包的漏洞。在修复时,可参考以下方式:

1、确定各依赖包的作用,确定各依赖包在系统中的使用情况,排查系统中涉及的版本不同但功能相同的重复依赖包。

2、根据整体修复建议,查找符合条件的版本。

3、查看各依赖包与其他依赖包是否存在依赖关系:如功能独立,则直接升为建议版本;如存在依赖关系,则需要同时升级相关依赖包,并在应用中验证兼容性。

问题解决机制

外部依赖库在升级过程中可能存在以下客观困难:

1、某一依赖包升级(如spring相关依赖包),与此依赖包存在依赖关系的其他jar包均需同步升级,工作量及影响均特别大。

2、依赖包升级后可能存在不兼容、功能不可用问题,除测试其编译是否成功以及基本功能验证之外,对于升级之后对系统带来的影响,还需进行充分的单元测试或系统测试。

3、可能有些外部依赖包来源于采购的产品,若需升级依赖包,则需联系产品提供商进行升级。

基于上述困难和问题,开发团队经过验证和评估,对于无法升级到建议版本、升级难度较大或联系产品厂商进行升级存在困难的依赖包,提请安全架构决策。

总结

  • 持续构建物料清单

    为每个应用程序持续构建详细的软件材料清单,从而全面洞察每个应用软件的组件情况。如果存在无法验证来源的开源组件,则不允许使用。

  • 强化软件供应链

    通过强化软件供应链来降低安全风险。这包括检查内部和外部源代码、支持脚本、配置文件和其他工件,并创建可信开源组件的内部存储库。而对外部存储库的使用要合理管理。

  • 风险管理

    通过制定策略确定可接受的开源组件、对在代码中发现漏洞或受限软件许可的合理响应,来管理风险。

建议

1、企业要有清单列表记录哪些产品使用了哪些开源组件。一旦某个开源组件出现漏洞,可以通过清单列表迅速排查。该清单列表也正是Gartner提到的材料清单,将在开源组件管控过程中发挥重要的作用。

2、企业要有清单列表记录禁用的开源组件,即,开源组件黑名单。对于那些安全问题比较多、风险较大的第三软件,应加入到这个禁用清单列表中禁止使用。

3、企业对于使用较多的开源组件,建议执行静态代码扫描或其他必要的安全测试,提早识别安全漏洞。对于发现的漏洞,提交开源社区,并促使开源社区修复。

4、对于开源组件的使用要有安全性指导(主要是规避一些因配置不当引入的安全问题)。

5、慎用对安全问题处理态度消极的厂商所开发的开源组件。

参考