如何正确地使用CI/CD工具

Posted by Pu Ming on Wednesday, July 6, 2022

一. 概述

2022 RSA大会上,来自Coalfire的副总裁和首席战略官Dan Cornelld的议题《What Executives Need to Know about CI/CD Pipelines and Supply Chain Security》从使用CI/CD管道的安全性出发,首先向各位观众讲述了什么是CI/CD管道,并提出我们为何需要关注CI/CD使用过程中的安全风险,之后Dan Cornell面向安全从业人员及DevSecOps实施人员讲述了使用CI/CD需要注意的安全风险,包括源代码仓库安全接入CI/CD管道可能引发的风险,引入第三方开源依赖库的风险,项目代码在构建测试、部署、打包、分发过程中面临的安全风险。最后,Dan Cornell提出了相应的安全建议并给出了未来6个月的具体DecSecOps实施计划。

二. 背景

DevOps 全称为 Development & Operations,在 2009 年被提出,其代表的并非一种具体实现技术,而是一种方法论。 DevOps 的出现最终目是为了打破开发人员与运维人员之间的壁垒和鸿沟,高效的组织团队通过自动化工具相互协作以完成软件生命周期管理,从而更快且频繁地交付高质量稳定的软件。 如 果 说 DevOps 理 念 实 现 了 软 件 的 快 速 交 付 、 那 么 CI/CD ( Continuous integration & Continuous Delivery & Continuous Deployment)便是实现这一理念的主要方法, CI/CD 的核心概念是持续集成、持续交付、持续部署。依托 CI/CD, 应用的整个生命周期(从集成和测试阶段,到交付和部署阶段) 可达到持续自动化和持续监控的效果。

如我们所知,DevOps影响的不仅包含开发团队(Dev)和运维团队(Ops),还应包含安全团队(Sec),在系统生命周期(SDLC Systems Development Life Cycle)中,安全团队常聚焦于运营阶段,因而往往忽视了开发阶段的安全,所以近些年“安全左移”的理念非常火,其强调安全因素应纳入应用开发的早期阶段,常见的,我们在开发(Dev)与运维(Ops)之间加入安全(Sec),也就是DevSecOps理念,其侧重点是将安全工具自身整合至CI/CD工作流中,且安全工具主要纳入应用的测试、发布和运维阶段。

随着技术的不断发展,用户可采用的CI/CD工具逐渐增多,除了关注工具自身的安全问题之外,如何正确的使用CI/CD管道,关注并及时发现各个阶段存在的安全风险也尤为重要。

三. 供应链攻击事件

供应链攻击是一种网络攻击,攻击者可利用软件或硬件来篡改服务程序,针对组织供应链中的薄弱环节实施攻击,从而导致服务程序被破坏。鉴于供应链自身的特性,恶意软件可以安装在供应链的任何阶段,且供应链攻击允许指定目标,若被攻击的供应商有很多客户,则受影响的数量会迅速增加[4]。此外,由于供应链依赖于已被信任并且可以广泛分发的软件,因而供应链攻击很难被检测。

3.1 Solar Winds供应链攻击事件

2020年12月,美国安全公司FireEye爆出有攻击者通过在SolarWinds软件中植入木马程序入侵了公司网络。该木马程序具有合法的数字签名并且伴随着软件的更新下发,借助软件供应链的特性,APT攻击者组织可对目标机构发起未授权访问,达到长期对目标机构的控制,并不断窃取核心数据。事件经历短短一周内就有超过200家重要机构受到影响,其中不乏一些全球科技发达地区的敏感机构,其中美国占比超过60%,包括美国国务院、国土安全部、国防部、财政部在内的多家政府机构均受到此事件的影响,事件影响力可谓巨大[4]。

3.2 Codecov供应链攻击事件

2021年,国外软件审计平台Codecov(该软件常被用于集成至CI/CD工作流中)遭受攻击者攻击,该事件直接导致近3万用户的隐私数据泄漏,究其原因,攻击者主要利用Codecov镜像Dockerfile中的错误配置提取Bash Uploader脚本(用户可通过该脚本上传测试数据)中的访问凭证,进而通过该凭证修改用户的Bash Uploader脚本[2],在长达1000多行的Bash Uploader脚本中添加如下两行代码[1]:

image
图1 Bash Uploader脚本中注入的恶意代码

可以看出,以上代码会将CI中所有的环境变量发送至第三方服务器,这些环境变量中可能包含Git访问凭证、API Key等敏感信息和密钥,攻击者可以进一步访问通过这些凭证访问的任何服务、数据和应用程序代码,危害巨大。

近两年供应链攻击事件层出不穷,分析并总结背后原因不难看出建立可信的软件开发环境、定期进行安全检查、关注依赖组件的已知漏洞、落实DevSecOps理念的重要性。

四. CI/CD应用过程中需要考虑的安全问题

Dan Cornell举例从数据流的角度看CI/CD管道安全,如图2所示:

image
图2 CI/CD管道示例图

可以看出示例中的CI/CD管道流程分为以下几个阶段:

  1. 开发者提交代码至源码仓库;
  2. CI/CD管道流程的构建阶段从源码仓库及开源仓库获取最新提交的代码以及相应依赖的开源组件代码;
  3. 构建结束后生成二进制文件,进入测试阶段
  4. 测试阶段包括安全测试、集成测试、单元测试三个部分;
  5. 测试完成后进入评估阶段,若测试通过进入后续的打包和分发阶段

上述流程结合一定的安全知识背景,我们可以看出安全风险可能存在于各个阶段,Dan Cornell从信息安全三要素机密性、完整性、可用性的角度阐述了这些风险,如从机密性上来看,主要涉及敏感数据泄露,如IP泄露、密钥泄露、漏洞披露为造成风险的主要因素;从完整性上来看,源代码植入后门、恶意挖矿或是其他恶意行为成为供应链攻击的主要一环;从可用性上来看,功能受到影响导致延迟发布与漏洞修复无法及时推送到生产环境,最终都会对软件交付产生不同程度的影响。

值得注意的是,随着业务越发复杂,系统架构从单体走向微服务化,CI/CD管道的复杂性也会相应增多,每个阶段都可能会产生大量的敏感数据,这些敏感数据往往会成为巨大的攻击杠杆。试想一旦攻击者拿到了源码仓库的访问凭证,那么整个CI/CD环境都可能遭到沦陷。因此,DevSecOps实施人员需要对数据的最终输出负责,评估软件CI/CD的运行环境,在CI/CD管道的每个阶段评估安全风险,如每一阶段涉及的服务种类、敏感数据、敏感数据存储、敏感数据分级、敏感数据传输加密等。

Dan Cornell从CI/CD使用的角度出发,阐述了各个阶段产生的风险,笔者将其进行了汇总,主要分为以下五部分。

4.1 CI/CD管道接入源码仓库的风险

通常情况下,CI/CD工具根据用户自定义的管道流程,在开发者进行git push或git pull等操作时触发接入源码仓库,在接入过程中由于源码仓库自身提供多种接入方式,进而扩大了风险面,图3展示了Gitlab提供的几种访问途径:

image
图3 源码仓库访问途径

可以看出除了常规的源码访问(push/pull/merge request等)、Web访问以及API访问,Gitlab还提供Webhook访问。在第三方开发团队对源码仓库进行push/pull操作时,若未对源码仓库接入进行有效认证,则可能会导致本地代码在CI/CD以外的环境中运行,进而造成源码不可控的风险。

4.2 引入第三方开源组件的风险

关于引入第三方开源组件的风险,通常包含以下四部分内容:

4.2.1 开源组件自身漏洞导致的风险

许多开源组件自身存在漏洞,不同风险级别的漏洞会导致CI/CD环境面临不同程度风险,例如若开源组件存在RCE漏洞,攻击者则可能利用该漏洞获取CI/CD管道中的环境变量,进而获取Gitlab或Github的有效访问凭证,最终接管整个源码仓库,引起巨大风险。

4.2.2 不安全的开源组件管理导致的风险

在CI/CD管道中,我们通常会引入第三方开源组件对项目依赖项进行构建管理。例如Java项目中,通常会引入Maven仓库,若我们的项目直接从Maven中央仓库进行拉取,我们就无法确定是否引入了含有漏洞的组件,进而可能导致组件漏洞被攻击者利用的风险。

4.2.3 攻击者为开源组件添加后门程序导致的风险

若攻击者拥有访问开源组件仓库的权限,进而可以通过为开源组件添加恶意后门程序,之后重新对外发布的形式,引发大规模供应链攻击的风险。若用户的项目源码中引入了含有后门的开源组件,攻击者则有可能利用该漏洞对CI/CD环境进行探测,进而导致整个环境沦陷的风险。

4.2.4 开源软件许可证导致的风险

开源组件的许可证类别较多,如常见的Apache License、MIT是相对宽容的许可证,这些许可证通常没有真正的限制条件,若将相应的开源组件引入自己开发的项目,并对外发布,仅需保留版权声明即可,不会面临使用上的法律风险。除此之外,还有一些顶级的开源许可证,例如GPL 3.0和AGPL,其为限制性的许可证,若引入了相应开源组件并进行商用,则会面临法律风险。

4.3 构建阶段的风险

构建阶段,CI/CD管道通常会引入插件对源码以及第三方开源组件代码进行构建,该插件实际上也运行在CI/CD环境中,对于开发者而言,插件是不受信任的,含有漏洞的插件可能被攻击者利用进而访问到CI/CD管道中产生的数据,并将数据传送至第三方服务器,如3.2中提出的Codecov供应链事件影响,受害者下载了攻击者精心注入恶意代码的文件,导致CI/CD中的环境变量泄露,攻击者可以利用这些环境变量窃取受害者隐私数据,造成巨大影响。

4.4 测试阶段的风险

自动化测试是CI/CD管道中必经的一环,自动化测试常包含集成测试、单元测试、安全测试这几类流程,CI/CD工具会调用测试插件(可能来自CI/CD环境外部或内部)进行测试,例如Gitlab的CI/CD管道默认支持引入开源代码审计工具bundler-audit、gemnasium等,这些开源工具是否可信是我们需要关注的重点,如测试阶段产生的流量是在CI/CD环境内部还是外部,若是外部将不受DevSecOps实施者的控制,可能进而会导致测试流量被代理到第三方服务器的风险,再如当测试阶段完成后,测试结果最终存储在哪里,若存储在外部,也会导致数据泄露的风险。

此外,风险漏洞管理也十分关键,如当Gitlab进行镜像扫描后产生了一系列待修复的漏洞,谁拥有什么权限访问这些漏洞很重要,若管理员分配了错误的权限,则可能导致未授权访问的风险,这里的未授权访问主要针对的是第三方团队的开发人员。

4.5 打包和分发阶段的风险

经历测试阶段后,CI/CD管道会评估最新的测试结果,一旦测试通过会将软件进行打包以及后续的分发,此处以微服务架构的项目举例,打包阶段时,各个微服务通过Dockerfile文件进行镜像构建,并进行签名后将镜像上传至仓库。分发部署阶段时,Kubernetes会从镜像仓库中拉取最新版本的镜像以完成后续部署。以上过程中可能会产生一定的风险,主要包括以下两方面:

镜像自身内容引发的风险

若业务镜像依赖的基础镜像含有漏洞,可能导致攻击者利用已知漏洞对服务自身或其他微服务发起攻击,若镜像中的应用代码含有漏洞,也将会导致被攻击者利用的可能。

镜像分发过程引发的风险

由于CI/CD与Kubernetes可能不在同一环境,因而可能导致攻击者在分发过程中趁虚而入,利用镜像来源的不确定性(恶意镜像签名)对镜像的传输过程进行劫持,并替换成恶意镜像,亦或是对镜像仓库直接发起攻击,造成巨大影响。

五. 面向CI/CD使用者的安全建议

在本次RSA演讲中,Dan Cornell面向CI/CD使用者提出了一些安全建议,

笔者将其进行了汇总,主要包含以下几部分:

针对4.1提出的风险,建议DevSecOps实施人员在CI/CD管道与源码仓库的接入上做好认证管理,并能够清晰的了解到项目源码的所处地,做好源码安全管控。

针对4.2提出的风险,建议首先梳理项目中所有依赖的开源组件,可通过SBOM(Software Bill of Materials)进行梳理,并采用SCA(Software Components Analysis)工具对开源组件进行漏洞扫描。其次,当项目中引入了新的开源组件,能够具备针对性的安全管控措施。最后,引入扫描组件的自身风险范围也应达到可控。

针对4.3提出的风险,建议对构建过程中的插件来源、插件需要访问的数据、数据最终的传送地进行确认,同时注意构建的频率是否异常。

针对4.4提出的风险,建议首先确认测试阶段是否包含第三方团队,若包含则需要确定测试产生的流量以及测试结果的最终去处。其次,需要确认扫描工具自身的安全性,做好实时修复漏洞的准备。最后,风险漏洞管理需要给予用户适当访问权限,遵循最小权限原则。

针对4.5提出的风险,建议首先从可靠源下载容器镜像,并定时对镜像进行漏洞扫描、漏洞修复以及后续的漏洞管理。其次,针对镜像构建过程进行签名,镜像拉取过程进行签名校验。最后,做好镜像仓库的安全管理,为镜像仓库用户分配合理访问项目的权限。

六. 总结

从近年RSA议题及创新沙盒入围的安全初创公司来看,DevSecOps已成为一项必不可少的话题,从最初的DevOps到安全左移的DevSecOps理念,这一过程必然会引起相应技术以及用户使用行为上的变革,将安全部分纳入DevOps并不难,难的是如何充分的践行DevSecOps理念,如我们所知,开发人员和运维人员通常没有安全背景,如何让其安全地使用CI/CD工具是一大问题,Dan Cornell的议题分享较为全面的阐述了使用CI/CD工具过程中需要注意的安全风险,并针对这些风险提出了相应的安全建议,可为各企业在DevSecOps的实际落地过程中提供一定参考。

七. 参考文献

[1] https://blog.gitguardian.com/codecov-supply-chain-breach/#what-happened-quick-timeline-of-events

[2] https://gist.github.com/davidrans/ca6e9ffa5865983d9f6aa00b7a4a1d10

[3] https://www.secrss.com/articles/35210

[4] 北京金融科技产业联盟《供应链攻击安全启示 - SolarWinds事件分析》

「真诚赞赏,手留余香」

Ming Blog

真诚赞赏,手留余香