1.概述
DevSecOps这个词相信大家并不陌生,也是近段时间说的最多的一个词,而这个词的由来从安全的角度来说是SDL思想的落地场景。
以前一直有人总纠结SDL和devsecops两者之间的区别是什么,其实这个问题并不难回答,SDL是安全左移思想的方法论,从开发的维度来说一般分为两种模式,分别为瀑布式开发和敏捷开发,所以DevSecOps是敏捷开发的落地场景。
很多企业为了适应快速开发迭代的模式,集成了一套DevOps工具链路,将开发与运维进行了整体的打通从而完成应用的快速部署,这同时也就给安全提出了挑战,新的安全模式也要适应敏捷的思想,从而DevSecOps场景的落地实践应运而生。
2.起点
在开发生命周期的起点是业务需求和架构设计,所以安全生命周期的起点仍然是安全需求分析和安全设计,我们建设了DevSecOps安全赋能平台,主要是进行安全设计库,安全威胁库、安全需求库的建设并进行轻量级威胁建模等工作,但是由于这些工作相对于敏捷开发来说无法进行流水线作业,所以我选择了SAST作为流水线作业的初始点。
SAST虽然误报率比较高,但是它的优势在于能够对项目源代码高度可视,基于代码规则可以更丰富检测安全问题,包括现在强调的个人信息等敏感数据的检测,以及其他数据安全相关的问题,在项目的后期对于这些工作的复盘无疑是延长了项目上线的时间,并且存在很大的漏报问题。
同时强调在代码阶段进行敏感数据的检测、CWE和OWASP分类漏洞的检测、安全配置的检测等工作相对来说成本是最低的,并且可以降低漏报的情况。
在SAST的选型阶段我们讨论了开源软件和商业软件的选型对比,我对FindsecBugs、Snoar Qube等开源工具以及商业的Fortify和其他国产工具分别进行了测试,工具集成并不复杂把插件安装到jenkins中并配置了GitHub的项目地址,当Jenkins构建的时候就触发了扫描引擎工作。
在这里特别强调一下,我们采用的是异步调用的方式,这么做的目的是由于项目代码本身是比较大的,如果进入等待状态会造成整个业务线的时间延长,这种方案相对于研发来说速度更快一些。同时在项目若干个分支进行合并的时候,也会触发引擎的检测,这么做的目的是单一分支的代码远没有项目整体的代码检测准确度更高,同时代码进行分支合并也是要触发安全质量评估,防止将存在威胁的代码引入到稳定版本中。
图(1)SAST触发流程
3.软件依赖性安全分析
SAST只是解决了自研代码的安全问题,但是现在大部分的业务系统中都是使用开源框架进行快速的开发,或者引入一些第三方中间件来迭代项目,但是这样也就把第三方的安全问题引入在业务系统中,并且这些第三方组件的漏洞在HW阶段往往发挥了关键性的作用,红队人员在HW过程中会收集业务系统使用了什么中间件以及相应版本信息,从而利用漏洞实现RCE。
通过对供应链安全的整理我们不难发现,高危的框架或者中间件有Struts2、Weblogic以及Jboss等,同时第三方常用的组件有fastjson、shiro、Jackson等。所以我们部署了SCA服务,SCA服务作为一个原子,在项目的构建阶段,会对项目的使用的第三方组件进行依赖分析,发现组件潜在的安全威胁,包含发现已知的CVE漏洞或者冒充的恶意组件。
但是我们也经常遇到研发总说有些jar包或者说是组件虽然引入了项目里,但是并未使用,所以我们也会对第三方组件进行动态探测,在UAT环境中,会对第三方开源组件运行时监测分析,在本阶段发现的漏洞对项目产生的价值更大。
图(2)SCA检测流程
4.UAT环境中灰度测试
从安全生命周期的角度来说,我们在开发阶段经历了代码检测,在项目的构建阶段进行了软件依赖性分析,解决了应用的大部分问题,守住了安全的质量门,但是SAST存在较高的误报,同时在DAST阶段因为各种原因导致漏扫设备无法爬取系统的所有接口,从而存在漏报问题。
所以在UAT环境中进行灰度测试同时解决了SAST阶段的高误报的问题也弥补了DAST阶段漏报的问题,在第一期建设时最终还是采用了插桩的方式,通过动态污点追踪技术分析代码的安全性,当参数进行进行传入时会被标记,分析参数的流动过程是否经历了过滤,如果在污点汇聚时未经过过滤,可以确定漏洞存在,这样就提高了漏洞检测的精确度。但是为了支持更多的应用的环境,所以考虑未来也会引入在扫描端发送payload模式。
5.写在最后
DevSecOps核心目标是构建研发运维一体化的安全作业环境,使组织成员能够敏捷的参与到安全体系建设中,从一个团队的安全到安全由人人负责的转变。虽然DevSecOps模型覆盖了整个软件开发周期的全过程,但在实践过程中大部分还是集中在开发和测试阶段,也就是代码安全扫描、供应链安全检测、UAT环境灰度测试、以及上线前的漏洞扫描。当开发和测试阶段的安全融入逐渐成熟后,安全理念将进一步左移到需求和架构层面,这也是第二阶段的主要目标。