供应链安全—组件漏洞和合规治理

Posted 面具与甲虫

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了供应链安全—组件漏洞和合规治理相关的知识,希望对你有一定的参考价值。

供应链安全—组件漏洞和合规治理

继上上周在公司内部做完Azure DevSecOps技术分享之后,突然发现组件漏洞的治理这一部分内容,对各大企业或厂商来说,业界有很多可圈可点的落地实践。当然,也有很多坑(甚至还无法解决),所以单独开一篇讨论企业内部的开源组件漏洞治理的话题,只谈论现象,不评价实际做法的对与错。于是就有了这篇文章。

一、组件及其与漏洞相关的几个概念

组件在IT技术中是一个特别普通的名词,对于不同的人来说,有着不同的理解或含义。

对于产品和前场部门来说,组件更多的偏向于业务组件,是业务支撑工具中的一个组成部分。对于技术部门或后场部门来说,组件可能是架构中的一个部分,或者是架构组件中的一个通用模块。这些都有可能被称为组件,所以,在这里,我们统一明确一下,我们这里讨论的组件的范围定义是:架构设计中应用层的技术组件,是基于OS层之上的与应用软件开发息息相关的组件内容

举个例子来说,操作系统的漏洞不属于本文我们讨论的组件漏洞的范围,但操作系统上安装某个开发语言的运行环境、依赖库则属于本文讨论的范围。

一般来说,组件通常跟组件来源的不同,分为开源组件和商业组件两类,其中商业组件又可分为外部采购和内部自研两种。无论是哪种形式的组件,其漏洞的治理过程大体类似,只是在关注的重点项上存在些许差异(这在接下来的文中会展开讲述)。

说完了组件的定义之后,接下来我们说一说与组件漏洞和合规治理相关的几个概念,因为在漏洞处理的过程中,需要基于这几个概念来采取相应的技术手段制定处置策略。

这几个概念分别是:

1.漏洞库:即漏洞数据库,主要是只大型的、公开的、业界公认的漏洞数据库。比如NVD、CNVD、exploit-db等。2.CVE :即为每个漏洞确定了唯一的名称,通过它能帮助安全从业人员快速地在漏洞数据库中找到相应的漏洞信息。3.CPE :即漏洞所关联的产品、版本、依赖路径或命名规范等信息,通过此信息,可以知道某个CVE所影响的组件版本和所在产品的依赖路径。4.CWE :即漏洞的类型,比如某3个组件都存在SQL注入漏洞,这3个漏洞的CVE并不相同,但CWE都可描述为CWE-89 SQL注入类型的漏洞。读者可以点击这里地址 了解更多信息。5.CVSS :即通用漏洞评分系统,通过对漏洞进行评分,来定义威胁的高、中、低以便区别,辅助制定漏洞修复策略。

二、漏洞处理的几个关键策略

安全从业人员每天的工作基本都或多或少地涉及漏洞相关的内容,漏洞往往成为众多企业安全人员苦恼的源头。在这里,可以用我过去分享的几张图片来阐述其处理的关键策略[^注1]。

漏洞成为众多企业安全人员苦恼的源头主要因为上述几个问题,在日常工作开展过程中,往往用扫描器一扫,会发现成百上千的漏洞,而这些漏洞又不知如何去处置它们。有的漏洞处理过了,一段时间后,它又有新的漏洞产生,又要来重新处理,烦不胜烦。面对这些问题,主要是安全从业人员没有制定好一套行之有效的漏洞管理策略。我们先来看两张漏洞生命周期与风险相关的图。

漏洞的产生来源于安全从业人员或其他人员的上报,这其中很大一部分漏洞是非安全从业人员发现的,只有少部分安全从业人员或者其他从业人员发现漏洞后并上报安全社区。未上报的漏洞,很大一部分被研发人员快速修复了,还有一部分一直未得到修复,也一直未申请CVE编号,甚至在某些社区流转交易。从漏洞修复和恶意利用的两个角度,我们可以从上图中看出,能抢在漏洞被恶意利用前、被漏洞利用工具发现前得到修复是最好的结果。

从这张图我们可以看出,从左到右,在漏洞的不同阶段,越往右,漏洞的风险值越高。基于这种情况,安全从业人员在漏洞修复时应做到有的放矢,修复哪些该修复的漏洞,如下图所示:

在漏洞修复时,工作应做到聚焦,不盲目关注所有的漏洞,其关键策略如下:

修复那些你的资产里包含的漏洞优先修复那些可以被远程利用的漏洞优先修复那些情报中表明正在被远程利用的漏洞优先修复那些在你的生产环境中发现的正在被远程利用的漏洞新的漏洞被大规模利用的窗口一般为7~14天,在这个时间窗口内完成打补丁、升级、替代方案最好的定义自己的漏洞评分模型,结合CVSS评分、漏洞利用难度、扫描后的漏洞暴露情况等综合判断

三、组件漏洞的产生或引入

说完了漏洞处理的关键策略,可能有的人会想:为什么要疲于奔命地去处理这些漏洞呢?这些漏洞是从哪里来的?没有漏洞不是更好么?理清楚这个问题,也是组件漏洞治理中很重要的一部分。在这里,我们先从组件漏洞产生的源头说起。

我们参考DevOps模式把整个软件的生命周期划分为以下几个关键阶段:

在上图的这条生产流水线上,组件漏洞被引入的途径主要有以下几种:

1.开发人员搭建开发框架时引入外部组件,导致存在漏洞的组件引入其中。2.代码提交后,在编译构建阶段,引入依赖的组件,携带有漏洞。3.部署阶段,安装实施时,引入外部带有漏洞的组件。4.运维阶段,之前使用的组件未及时更新导致存在漏洞或者运维过程带有漏洞的组件。

通过上述1~4 种引入漏洞的方式分析,我们大体可以得出这样的结论: 控制带有漏洞的组件引入生产环境,及时更新存在漏洞的组件可以保证组件不存在漏洞

下面我们就依托这条流水线,来谈谈业界是如何治理组件漏洞的。

四、 组件漏洞合规治理的整体思路

在前面两篇关于Azure 云的DevSecOps架构分析的文章中,我们也提及了组件漏洞治理的相关内容,这也是业界通用的组件漏洞治理的主流方式。

我们对照上图的流水线来看,组件漏洞治理的主要途径有两种:

1.限制外部存在漏洞的组件的引入2.对于已引入的组件,检测组件的漏洞并及时更新。

首先,我们来说说第一个,如何限制外部存在漏洞的组件的引入。

4.1 限制外部存在漏洞的组件的引入

对于限制外部存在漏洞的组件的引入,业界采用的方式通常有以下两种:

1.控制开发人员的IDE,比如使用云端的IDE,在IDE中集成插件,检测对外部组件或依赖组件的引入。

2.控制网络访问,在网络层面切断开发环境与外部组件来源网站的直接连接,通过组件仓库或可信软件仓库的形式,阻断存在漏洞组件的直接引入。

第一种:云端IDE 这种方式很好理解,即开发人员在云端开发,使用云端的IDE作为开发环境,编写的代码也存储在云端,提交后也存储在代码仓库上。

但这种方式对很多企业来说,难以落地。光云端IDE的解决方案就令很多企业头疼,更别说云端开发IDE的易用性、性能等影响工作效率的问题,只有TOP N的大厂商才开展此类实践的,比如Google。

第二种:控制网络访问 这种方式的实施原理比较简单,易于理解,难点在于工程化实施。其原理图如下所示:

4.2 检测组件的漏洞并及时更新

对于检测组件的漏洞并及时更新,这种方式,目前应用比较普遍。很多企业都在使用SCA软件来检测组件漏洞,唯一不同的是,真正的落地效果只有企业自己知道有多失望,很少有SCA产品能真正解决企业的组件漏洞问题。在这里,对于此种方式下的漏洞治理,主要推荐如下两种思路:

1.对于已提交到研测环境下的组件,推荐使用依赖库/组件检测与更新方案。

2.对于生产或预生产环境下的组件,推荐使用基于安全基线的更新方案。

上述两种思路,接下来的内容将重点围绕此展开叙述。

五、 依赖库/组件漏洞治理实践

在上文中,我们也提及到,这种处理思路是目前很多企业的主流治理方案,但在落地时存在很多的问题,导致最终成效不佳。下面,我们就来聊一聊与此种思路相关的技术和处理策略。

5.1 依赖库/组件检测的基本知识

依赖库/组件存在于我们的应用中,当我们想方设法去检测它们时,首先得了解其在应用中存在的形态。下图中表示了当前环境下依赖库/组件存在的基本形式。无论是Java开发语言还是C++、python等开发语言,其存在路径基本类似。

如上图所示,在一个类库或应用中,可能存在同一依赖库/组件的不同版本,也会存在同一依赖库/组件在不同的依赖路径。当我们做依赖库/组件漏洞检测时,需要将每一种情况下的依赖路径都要检测出来,这样才会保证不会存在遗漏的情况。

一般来说,检测一个组件漏洞,有多种方式,比如搭建一个测试环境demo,验证此漏洞是否存在;比如通过源代码分析,此漏洞是否存在;比如,使用已知验证过从POC;比如,有的组件安装完成后,在系统特定目录或注册表存在某些特殊标志,可以扫描文件目录或注册表来检测。这里,我们统一使用SCA软件分析来检测漏洞的方法,其原理主要是目标源代码或二进制文件进行特征提取,从而确定组件名称和版本号,再通过CVE与CPE之间的映射关系,快速检测是否存在有漏洞的组件。使用SCA的好处是,对操作人员来说,屏蔽了上述不同检测方式涉及的技术细节,能保证组件漏洞发现的质量,减少漏报误报的情况。

5.2 依赖库/组件漏洞检测的范围和目的

之所以推荐大家使用SCA软件的原因,是由我们需要检测的范围决定的。一般情况下,我们会检测组件、类库、甚至某些应用,它们的文件包大小不一,大的可能会以GB为计量单位,文件的引用或依赖嵌套很多个层级,同一个组件的不同版本在多个不同的地方被引用,非自动化工具处理效率非常低。而且在前文中我们也提及到,很多漏洞是没有CVE编号的,需要依赖于静态分析。我们需要检测的对象可能存在不同的形态,比如jar包、js文件、二进制文件等等。所以,一个趁手的工具软件是必须的。

通过SCA软件快速地帮助我们发现组件中的漏洞及其存在路径,以及周边的相关信息,比如开源组件的协议,如果是GPL系列的,则需要关注使用的合规情况。比如检测出来的漏洞及提供相关的修复建议,是建议升级补丁还是升级版本。这些信息,也是SCA软件提供的核心竞争力,也是帮忙我们快速达成最终目的的支撑能力。

我们之所以做组件漏洞检测,其目的是了解当前整体应用在组件使用这块的风险,确定哪些组件的漏洞需要立即修复,哪些组件的漏洞当前不可以修复,可以通过其他缓解措施来降低风险。

一般来说,对于组件漏洞,有如下几种修复方式:

1.升级版本 这种方式很好理解,不过多解释。重点提一下, 编译构建时的自动替换升级是比较好的选择。2.打补丁 这里的补丁分两种,一种是可以通过官网下载的补丁,还一种是自己具备研发能力,修改开源代码升级的补丁。无论是哪种,都需要关注组件的依赖路径,防止遗漏。3.不修复组件,通过其他方式消减。比如虚拟补丁,防火墙策略调整等。

5.3 通用型SCA路人甲级方案

取这个小标题,是因为此方案目前比较普通且普遍。

5.3.1 SCA选型

在选择SCA软件时,我们需要关注几个关键因素,它们直接影响你的选择结果。这些因素是:

1.检测与修复:SCA软件之前的定位主要是检测,如果能提供自动化修复或者半自动化修复,即使是给出漏洞修复的最佳建议也是对漏洞处理生产力的极大提高。因此,选择产品时,除了关注检测能力外,还需要关注修复支撑能力。2.漏洞数据库质量:在前文我们提及了SCA软件的基本原理,所以漏洞库的更新频率、及时性,包含的特征、指纹信息量将关系到最终的检测质量。3.支持的编程语言:每个SCA软件支持的开发语言不一样,要根据你当前的需求以及未来可能存在的需求,选择SCA。

在Forrester 2021年的SCA报告中[^注2],从License风险管理、漏洞识别、主动式漏洞管理、策略管理、SDLC集成等方面,对当前SCA市场上的产品进行象限划分,如下图所示:

同时,对于上图的象限划分,提供了一组基础数据,如下图所示,这些数据,对你选择SCA产品会有很大的帮助。

基于这组数据,其背后的供应商和其软件产品如下图所示:

5.3.2 SCA集成型组件漏洞运营思路

SCA集成通常是指SCA软件与CI/CD的集成,比如通过Jenkins插件集成,通过API接口二次开发集成。无论是哪种形式的集成,其目的都是将SCA的组件漏洞检测工作整合到当前的流水线上,提高检测工作效率。

在SCA与CI/CD的集成过程中,一般对任务的执行选择异步任务或并行任务,很少有顺序执行的。如下图所示,是很常见的一种SCA软件使用方式。

SCA检测任务与流水线的主任务并行执行,异步反馈执行结果。而对于扫描结果提示的组件漏洞数据清单,到底是如何处理,有些企业在此处使用的是人海战术去推动,也有的到此就结束了。

一种比较好的闭环思路是,在SCA提供的支撑能力不足的情况下,在此基础上做二次开发和封装,根据漏洞处置的策略,确定后续操作流程。这里,常用的策略有:

1.组件黑白名单 黑名单是指业界公认的那些存在诸多漏洞,禁止使用的组件。白名单是指在历史的漏洞记录中,那些即使出现漏洞,利用条件也是非常苛刻,难度非常高,基本都不会去更新修复的组件。2.修复优先级 是指一旦存在某个组件漏洞,必须修复的,且是高优先级修复的。针对此类漏洞,在二次开发时补全修复方案和建议,自动触发漏洞修复工单,跟踪漏洞闭环情况。其他优先级低的,可以关联代码仓库或迭代版本,跟踪漏洞修复情况。

此时,整体的漏洞处置流程如下图所示:

除此之外,通常二次开发的时候,基于以上的基础架构,能提供组件漏洞快速定位查询功能。比如某个组件新爆出一个漏洞,能通过此功能,快速查询当前的那些项目、什么版本、在哪些服务器上使用了带漏洞的组件。这一点,对于组件漏洞的应急响应来说,非常重要。

5.4 参考型 Azure云 网红级方案[^注3]

如果上述的所有方案或治理思路都还不够体系化,那么Azure依托Github+Dependabot的组件漏洞治理方案会让你更养眼(在前一篇公众号推文文章中已经提及)。Github在原有平台上集成了Dependabot,成为Github的组件漏洞检测方案。

5.4.1 Dependabot基本特性

Dependabot于2019年被Github收购,未收购前其官网为https://dependabot.com,想了解技术特性相关信息可以访问此网址。在Github上,其主要特性如下:

1.与Github原生集成,通过简单配置即可使用。2.通过监控不同开发语言的代码仓库,比如 Ruby, Python, javascript, Java, .NET, php等,检测后自动推送组件安全告警或更新建议。3.用户可以自定义组件的周期性更新策略,比如每天、每周、每月等。根据更新策略,Dependabot创建PR去跟踪更新闭环的流程。4.与Azure的CI/CD流水线集成,自动更新部署包,推送到生产环境,并支撑不同形式的升级方式,比如蓝绿部署和金丝雀发布。

5.4.2 Dependabot工作原理

在Github上,默认情况下,public仓库会默认使用Dependabot配置文件,private仓库用户可以自己添加或者仓库管理员添加此文件,不授权的情况下无法使用。一般在.github文件夹下,为dependabot.yml 文件。当这个文件存在时,将触发Dependabot对该仓库的组件依赖安全检测。

Dependabot工作时,通过读取仓库目录下的依赖配置文件并解析,来检测组件的依赖情况。目前支持的解析格式和开发语言如下表所示:

从上表我们可以看出,大多数开发语言都能支持。检测完成后,将根据配置文件中的更新策略(配置文件的相关细节请移步这里阅读),来确定是否触发更新的PR。一个完成的PR闭环如下图所示:

一个完成的PR闭环会显示更新了哪些组件的哪些漏洞,当前的测试、兼容性建议如何,帮助你来决定是否做合并操作。而在Azure的流水线上,其整个流程架构图如下:

与上述不同的是,将由流水线推送到Azure资源管理器,除此之外,在Dependabot整合到GitHub原生平台之后,Dependabot原有的几个功能无法使用或被修改为需要人工参与,从风险控制的角度来说,我可以理解的。如果全部都是根据配置文件自动升级,则过程中某些风险对管理Dependabot的Github来说不可控。这几个功能是:

1.实时更新功能 即新的组件包发布后即时获取新的组件包。2.自动合并功能 即发现新的组件包,测试验证后,自动更新组件在仓库中的依赖。在上文中,我们也提及到,Github PR闭环中需要人工确认,即是这个功能的变化。

六、 小结

通过上述的案例分析,我们可以看出组件漏洞的治理是一项复杂的安全活动,而我们面对的企业现状也比较复杂。有的没有CI/CD流水线,有的没有SCA软件,更别说学习Azure来抄作业,做一套体系化的治理方案。即使是Github,在集成Dependabot后,也是将自动化更新的能力修改为流程关键环节需要人工确认来推动下一步流程。所以,如果目前你的企业这块工作没有做好是正常的,别气馁,向着美好的目标奔赴就是,我们一直都在路上。


参考资料:

[1]: 《The Threat Intelligence Handbook》第2版

[2]: https://www.whitesourcesoftware.com/resources/research-reports/the-forrester-wave-software-composition-analysis

[3]: https://docs.github.com/en/code-security/supply-chain-security/keeping-your-dependencies-updated-automatically

供应链安全——二进制层面的检测技术

闭源软件中复用开源组件检测

组件复用型漏洞

定义:因复用含有漏洞的组件(第三方库、开源框架等)而引入的软件漏洞
现有检测方法

组件复用型漏洞的检测

核心技术: 闭源二进制软件的开源组件复用检测

对于源代码与二进制代码间的复用检测受到复杂的复用关系影响,即检测复用时对简单的复用可能有用,如zlib.dll与zlib库,而对多层调用就失去了效果。
主要用到的方法如下:

因此,识别问题不仅仅时简单的代码相似性检测问题,需要识别复杂关系,因此,复用检测的工作变成了流行的代码相似性检测+复用关系识别
现有工作准确率不高的原因

  1. 没有符号信息,完全依赖于代码特征比对
  2. 使用的代码特征太少,很多代码无法提取到有效特征
    原因:代码特征普遍受编译优化影响大,无法使用
  3. 没有考虑复杂复用情况,从而引入大量误报漏报

解决方案

  • 补充抗编译优化的代码特征,并为新特征设计合理的匹配算法和权重算法
  • 对复用类型进行划分,针对不同类型进行针对性识别

1、代码特征选择

常用代码特征与新增代码特征评估:

2、代码特征提取

二进制代码特征提取方法:基于IDAPython提取导出函数、字符串、switch/case、if/else
结合编译信息的源代码特征提取方法:
源代码特征提取方法:基于clang和llvm开发特征提取工具
特征所对应代码片段:

3、代码相似度计算

4、复用类型划分

  • 单一复用

1 bin -> 1 src

  • 混合复用

1 bin -> N src

  • 部分复用

N bin <- 1 src

  • 嵌套复用

1 bin -> 1 src -> N src(嵌套复用是假式复用,应被去除)

闭源软件中复用开源组件版本检测

在检测复用组件的基础上,检测复用组件的版本,因为不同版本的影响的漏洞有限

从待检测二进制文件中提取代码特征,和预先准备好的从源代码中提取的特征进行比较,现有工作如下:

局限性:

版本敏感特征选择

选择的核心标准:不同版本之间的区分度拉满

全局特征
区分度公式:
举例如下:

函数级别特征

粗匹配

全局级别特征匹配方案 -> 粗匹配阶段
特征匹配方案:精准匹配——全局级别特征在编译前后不发生变化

精匹配

函数级别特征用来定位函数,整个函数作为一个整体,所以采用基于相似度的识别方案。

具体的匹配算法:

参考文献

《软件安全原理》——霍玮

转载请说出处:from 信安科研人

以上是关于供应链安全—组件漏洞和合规治理的主要内容,如果未能解决你的问题,请参考以下文章

供应链安全——二进制层面的检测技术

应用程序不合规并被删除:安全漏洞:不安全的主机名验证

ChatGPT类AI软件供应链的安全及合规风险

ChatGPT 类 AI 软件供应链的安全及合规风险

K8s:开源安全平台 kubescape 实现 Pod 的安全合规检查/镜像漏洞扫描

K8s:开源安全平台 kubescape 实现 Pod 的安全合规检查/镜像漏洞扫描