DevSecOps实践:如何在研发过程中做好供应链安全

2023-06-28 14:48

DevSecOps与供应链安全

很多企业都建立了DevOps流程,但安全基本还处在流程之外,没有融入传统DevOps流程,导致安全一直都是敏捷交付的瓶颈。本篇内容我们将从DvSecOps和软件供应链安全的角度来谈谈研发过程中的安全问题。


01   DevSecOps——供应链安全治理基石

在很多企业寻求DevSecOps解决方案的背景下,安全左移的理念愈发重要。美国国防部白皮书中也提到DevSecOps落地的核心就是安全左移,但其中强调的安全左移是在研发阶段做安全测试,这样的左移并不彻底。真正实施安全左移比较彻底的是微软的SDLC理念,强调安全应该在更早期阶段介入


经过近几年的不断实践,DevSecOps已经做到了比较深度的安全左移,并不只是在研发阶段做安全测试,而是在需求阶段就考虑安全,甚至是在立项阶段就介入安全。


安全左移的价值不容忽视,我们知道在不同阶段发现并修复问题的成本是呈几何增长的。如果在研发阶段发现并且修复问题的成本是“1”,在测试阶段修复问题的成本就是“2”,在发布阶段修复问题的成本就变成了“10”,在运行阶段发现并修复问题的成本就会是“100”,甚至于对业务运营的影响难以估量,因为有些安全问题就是一个企业的生命线。



02   供应链安全治理落地难点

供应链安全治理环节分散。在编码、编译、部署等环节都容易出问题。


研发修复成本高、安全问题修复滞后,频繁回归


供应链安全治理依赖多工具能力。单一工具难以覆盖供应链安全所有的治理对象,现在提到供应链治理工具基本都是SCA,但是像操作系统、中间件这些都是在供应链治理过程中需要考虑的治理对象。


安全是孤岛而不是流程。安全工具独立使用,安全漏洞只存在于安全工具内,没有跟研发、测试、安全、运维流程打通,没有融入流程,进而导致安全工作只能阶段性介入,影响交付节奏和周期。


缺乏全流程治理经验。基于安全木桶理论,补足安全短板,做到供应链安全的全面治理也有赖于安全经验。


没有供应链资产管理。这一块主要是针对SBOM解决方案而言,SBOM只是一个静态的软件物料清单,如果发现0day安全问题,扫描所有代码仓库的效率显然太低,而且扫描之后能否快速呈现有问题的软件,也是需要去考虑的,从资产管理以及事后盘查等角度出发。


03   交付管道


CI/CD交付管道,也就是流水线,现在的安全工具基本都是采用编排的形式接入到流水线中。因为安全工具种类繁多,不可能每一个都登录进去制定扫描计划,加上现在很多核心系统都实现了服务化改造,在每个工具上针对每个服务应用去创建检测任务的工作量对安全团队来讲几乎无法完成,所以现在的安全检测工具已经上升到了编排的维度。


值得一提的是,尽管在流水线中可以同时发起多个检测工具进行检测,但在实际情况中并不会这样来编排流水线。如果是研发测试环境的流水线,通常会将安全检测全部靠后,因为此时要做的事情是快速把应用构建起来进行部署,然后让研发和测试去验证功能。验证完功能之后,再去看安全检测工具检测到的漏洞,因为在部署之后,安全检测工具同时开启检测,功能测试与安全检测工作几乎可同时完成。


如果是针对上线的流水线,所有安全检测工具编排会尽量靠前,而且此时安全检测工具必须要有安全卡点的能力,也就是在每个工具中设置一个安全阈值,比如针对SCA工具,定义它的超危组件不能超过一个,否则不允许执行后续的流水线。通过这种方式,就能实现质量一致性保障通道。所谓质量一致性保障,就是无论在何种业务研发背景下,每次通过流水线交付出去的制品都符合质量要求。这就能形成一种文化,即研发人员在提交代码时就会思考能否过安全卡点,如此思考安全问题的方式也就得以改变。


此外,现在针对安全工具的很多解决方案是在流水线里写一个脚本,把代码提交到白盒检测工具中扫描,然后去拿检测结果,但是现在很多微服务应用少则几十个,多则成百上千个。面对上千个应用,每天提交一次代码到流水线中检测,任何一款白盒工具能无法支撑。所以将安全工具放到流水线中,常态化、自动化执行对于安全工具的技术要求也发生了根本性的变化。它并不是在流水线中简单写个脚本去调用检测工具的检测接口,然后获取数据,而是要考虑每一种检测工具的检测能力是分布式的。


所以在DevSecOps流水线中可以衍生很多跟现在企业实施思路不一样的地方,我们可能要评估现在的流水线能否承载核心系统未来的业务发展,整个安全执行的效率是否达到要求。无论在什么状态下,软件质量都要符合风险可接受的范围。



DevSecOps安全能力体系建设

DevSecOps有两个发展方向,一个是One by one,一个是All in one。


One by one就是基于Jira、Jenkins、GitLab的解决方案,组合在一起形成一个自动化流程。All in one是一体化平台,它不是简单地将工具集成进来,而是在平台上重新开发。


01   DevSecOps一体化平台

DevSecOps是效率的代名词,之所以很多企业一直在提倡它,是因为供应链治理工作的复杂性,除了供应链治理以外,还要考虑云原生安全、应用安全、数据安全、合规安全等,企业要想做好这些安全工作比较困难。White Hat组织在2021年针对全美公共事业部的互联网应用发布了一份安全调研报告,报告显示制造业有60%以上的企业存在可利用漏洞,暴露窗口期在365天以上,金融行业有40%以上的企业存在此类问题。由此可见,国内的在线运营系统,其安全状况也不容乐观,在这种情况下一体化平台将是发展的必然趋势。


根据GitLab和Jenkins的官网介绍,GitLab的配置文件叫gitlab-ci.yml,是解决持续集成的问题;Jenkins的配置文件是Jenkinsfile,是持续部署的解决方案。国外的CI/CD流水线比较严谨,CI与CD的功能更加明确,但是简单的将GitLab与Jenkins相加并不等同于CI/CD,所以真正在做CI/CD时必然是向一体化的趋势发展。


在一体化的平台框架之下,可以进行大量的数据挖掘。需求从邮件列表提出来,进入到需求中心,到产研环境,再到预发环境,然后上线。需求这一数据对象流经很多工具,每一个工具停滞的时间都由不同角色的工作来决定。DevOps讲究高效的端到端价值流交付,但是像需求平均交付周期、需求流负载、产研周期等指标都统计不出来,就不能算真正的DevOps,只是一个自动化流程而已,这也是很多企业的现状。所以一体化的DevOps,也将是未来研发效能的发展趋势。


02   DevSecOps安全能力体系


DevSecOps安全能力体系,就是针对整个研运流程去做安全能力抽象。比如在设计阶段做威胁建模,但现在做威胁建模的企业并不多,因为它的落地非常依赖于负责人丰富的经验,除了要懂安全,还要懂渗透、攻击、研发、架构、业务等等,才能考虑怎样去解决这些风险。




在供应链这一方面需要做很多检测,大部分方法是直接引用第三方组件,我们在供应链中经常会提到开源软件,即开源组件或第三方组件,因为开源软件的范围太泛了。比如Redis缓存,从第三方组件的角度来考虑,就是在代码里引入了一个Redis的调用组件,这个组件可能有问题,但是Redis部署的服务可能也有问题,所以开源软件治理的范围从组件和软件两个角度来讲,就有两个不同的维度需要去治理。


Redis的环境基本上都要进行基线扫描,甚至要人工去做安全配置检查,所以安全不能只想着引入工具和如何使用它,而是这个工具能解决什么问题,接下来要怎么把它放到流程里面,自动化建立起来。


接下来,如果要做供应链安全治理,只需要建立一个视图即可,能查到所有应用资产下面的组件漏洞信息,以及每一个部署环境的信息。所有的检测任务或者漏洞的修复情况,只需在流程中完成即可。




DevSecOps实践落地

实践一:IDE安全自测


一旦建立流程之后,必须确保让研发有一个高效的流程可以提前感知,因为研发会考虑提交的代码要过安全卡点,否则会影响KPI考核。而且代码提交到线上之后触发CI流程比较耗时,如果在IDE层面有检测插件,研发就可以快速自测,知道自己引入了哪些有问题的包,经修改检测无误就可以将代码上传。


实践二:创建安全私服


如果使用第三方私服,或者不对内部的私服做任何安全管控,在做软件构建之后就需要依赖大量检测。如前所述,在测试阶段发现漏洞的修复成本是研发阶段的两倍,因此为避免在研发阶段投入更多成本,可以在所有的第三方组件进入私服时进行安全审计,只有符合安全要求才能进入私服。其实这也是SCA工具的一个功能,它开放了一个网络代理,当我们去公共的组件仓库下载组件时,组件会经过代理的检查,检查通过再将其放到仓库中;如果检查有问题,可以有不同的处理策略,比如先放到一个缓存队列中去做评估或者直接拒绝。在具体实施时,可以再配置外部私服,然后动态去做入库检测以及构建的动作。


实践三:建立一致性质量内循环


CI/CD是两个阶段的流程,但是现在企业能做到CD的并不多,因为CD有不同的理解,一个是持续交付,一个是持续部署。持续部署是一个技术行为,跟CI差不多,但是持续交付则需要非常多的能力来支撑。CI环节也不是一个过程,因为在不同的环节有不同的流水线去做安全工作,整个安全工作已经实现了一个常态化自动化,敏捷的特点就是小步快走,检测到增量漏洞后快速修复,这个增量漏洞并不只是定义到修复超危漏洞,而是低危漏洞也要一起修复。这是进入了一个比较好的状态,质量内循环建立起来会非常高效,软件安全的质量控制也会更加高效。


实践四:建立安全管控机制


安全管控机制,就是前面说到的安全工具卡点,现在几乎是没有哪一个安全工具有卡点能力。一般做安全卡点,都是自己通过写脚本,然后去判断当前的安全漏洞数据情况。现在的工具可以去配置添加不同的卡点阈值要求,然后去选择执行策略,比如说终止或继续,同时还可以快速通知到相关的责任人。