本文将从传统 SDL 开始,介绍百度从 SDL 到DevSecOps的演进历程。全文涉及 SDL 的痛点、DevSecOps 建设初衷、实践形式、落地思路,以及落地后的效果与收益,也会介绍DevSecOps在云原生时代的探索思路与落地场景。如果你正准备或者已经参与到企业DevSecOps建设的相关工作中,这篇文章或许能够给你的工作带来一些启发。
一、轻量级SDL,百度的前DevSecOps时代
作为一家大型互联网公司,百度具备着所有大型公司和互联网公司的典型特点,业务体系繁多、业务数量庞大,业务迭代迅速。
在百度内部,业务研发模式有别于传统的SDLC模型,更接近于DevOps 模式,CI/CD工具集成和自动化程度高,产品迭代频次多、周期短。
面对这样的业务研发场景,传统通过输出人力到业务团队,全流程跟进和解决业务研发生命周期的安全问题的方式已经不再适合。安全团队不能,也不可能将人力覆盖到所有业务。因此,安全团队势必需要构建通用性的产品安全基础设施,将其嵌入到产品研发流程中,然后配合重点业务的小范围安全评估,来实现高可用、高自动化的软件研发生命周期安全保障。
在百度,我们将这种方式称之为轻量级 SDL,即通过少量的人力投入,以高自动化、高 CI/CD 集成的方式解决业务产品的安全问题。在轻量级 SDL 建设初期,我们根据实际业务场景,构建了百度的自动化漏洞检测系统,并将其嵌入到业务测试上线流程中,具体图示如下:
通过轻量级 SDL 建设,我们以不足 10 人的团队规模,支撑百度 80% 以上业务的上线前安全检查,并在过去的几年时间,保证百度线上业务安全问题数量每年降低30% 以上。
当然,上图中描述的轻量级 SDL架构也存在一些问题和痛点。
虽然通过在测试上线阶段嵌入了自动化安全测试流程,能够帮助业务在上线之前提前发现安全问题,降低安全风险。但是由于业务团队相对缺少安全意识和视野,经常误认为保障业务安全只是安全团队的工作,认为自动化安全测试是安全团队给业务团队增加的额外负担。在这种情况下,业务团队在面对自动化安全测试流程检查出的问题时,也常常是 case by case 的解决,并没有深层次的解决安全意识和安全编码相关的问题。
对此,我们整理了轻量级 SDL 初期建设完成后亟待解决的一些问题,并决心解决:
- 自动化安全工具很难覆盖到产品的需求设计阶段。
- 安全只覆盖了产品研发的编码和测试阶段,并没有实现全链条覆盖。
- 绝大多数产品的安全措施集中在测试阶段,流程滞后、修复成本高、效率低。
- 仅通过自动化安全工具的嵌入,很难与业务团队建立安全协同机制。
- 非常规型安全漏洞,很难在测试阶段进行自动化发现和收敛。
二、构建DevSecOps的初衷
针对上述问题,我们期望对轻量级 SDL 架构进一步完善,建设一个产品研发全流程覆盖、高自动化集成、强调安全与业务协同的业务安全保障框架。
我们期望通过产品研发全流程的安全措施建设,持续提升业务团队相关人员的安全意识、安全编码习惯以及对安全场景的理解,让业务在产品研发的各个阶段都能实现高效、安全、可靠的交付,将安全漏洞和缺陷消灭在问题的根源。
这些都与 DevSecOps 的理念不谋而合,所以我们决定在轻量级 SDL 的基础上,构建百度的 DevSecOps。
三、百度DevSecOps实践
我们在建设DevSecOps时,主要侧重以下方面:
- 打造高自动化的产品安全工具链: 利用产品安全工具在产品研发的各个阶段进行自动化漏洞挖掘,快速发现漏洞的同时确保不会降低研发效率
- 在全公司范围内的落地:设计普适性的、能够覆盖百度所有业务并真正落地的 DevSecOps 框架
- DevSecOps安全运营:对各个产品安全工具进行安全能力建设与工程化运营,并支持特定业务线的定制化需求
- 云原生场景的探索:在云原生基础架构变革大趋势下,讨论百度DevSecOps与云原生场景的融合与落地措施。
后边的章节会按照这个顺序逐一阐述。
3.1 产品安全工具链打造
业务安全保障的核心工作之一就是降低线上漏洞数量。在 DevSecOps 的建设中,想要大幅度降低线上漏洞数量,其核心是构建和利用好各种自动化漏洞发掘工具,并将其与CI/CD进行自动化集成,确保执行漏洞发掘的时机准确、及时,并且不会影响研发效率。
在我们的解决方案中,主要涉及到DAST、SAST、IAST、RASP等工具的设计与实现,感兴趣的同学可以阅读之前发过的相关文章:
- DAST
分布式Web漏洞扫描服务建设实践系列——扫描架构演进及要点问题解决实践
- SAST
- IAST/FAST
- RASP
3.2 公司范围落地实践
3.2.1 总体落地思路
在百度,产品研发流程被抽象成「需求」、「开发」、「代码准入」、「测试」、「上线&验证」五个阶段。每个阶段都有完善且严格的规范和要求,例如在代码准入阶段,要求正式提交的代码必须严格遵循百度代码风格规范,否则不允许提交代码。这些规范保证了百度的产品能够优质、高效和稳定的交付,我们称之为研发工程规范性模型,下文简称工程规范性模型。
百度工程规范性模型将产品研发各个阶段的规范和措施的完成度量化为分数,以产品和代码仓库的维度进行统计和公示,并在公司层面建立了工程规范性评分基准线。
我们在思考如何设计和落地 DevSecOps在各个研发阶段的安全能力时,发现 DevSecOps 的内核与工程规范性模型是高度相似的,都是通过在产品研发的各个阶段设计规范、工具、检查,来提升研发效率、产品质量、工程师素养。
再一次的不谋而合,促使我们决定依托于百度工程规范性模型构建百度的 DevSecOps 模型,推动DevSecOps工具链与相关规范的落地实施,并借助于百度工程规范实现快速推广 DevSecOps 到全公司的效果。
百度工程规范性模型要求所有接入的规范、工具、方法都要具备高自动化以及高 CI/CD 集成的能力,这一点实际我们在SDL时代就已经完成。所以在落地DevSecOps时,我们只需要按照该模型的标准,将各项产品安全工具、产品安全措施转换为可量化、分步实施的安全检查项。
通过将安全检查项合理放置在产品研发的各个阶段中,我们实现了研发全链条覆盖:
同时得益于高度自动化的安全工具链支撑,虽然我们在研发流程中深度嵌入了很多安全检查项,但是依然可以满足DevOps时代产品快速迭代的需求。例如,我们将第三方高危组件、安全编码规范等安全检查项嵌入到代码准入阶段,自动化扫描任务可以在分钟级完成,完全不会影响代码的正常提交。
下面的章节,我们会介绍在 DevSecOps 落地过程中,在各个研发阶段涉及到的一些具体安全措施和安全工具。
3.2.2 需求阶段
- 需求设计安全解决方案
在DevOps模式下,需求、设计阶段通常是整个研发周期中最灵活且难以控制的。由于业务量庞大、业务快速迭代的特点,很多传统产品安全措施如:威胁建模、安全设计评审、业务设计安全评估等工作难以覆盖到所有业务。
对此,在百度DevSecOps方案中,我们针对不同业务场景提供了一系列安全解决方案,覆盖Web业务、App业务、IoT业务、toB私有化、用户隐私等业务场景,基于多年SDL安全经验积累,对各个业务中容易出现风险的地方提供了统一化的安全解决方案,这些方案有的是规范约定,有的是bad case枚举,还有的是基于安全SDK的解决方案。
同时将其集成到百度工程规范指定的需求管理产品iCafe中。当业务线研发人员、PM创建需求卡片时,可以根据自身的业务场景选择对应的安全解决方案,并在研发前完成规范、安全方案的学习,从而在研发编码阶段尽可能避免这些问题。
3.2.3 开发/代码准入阶段
- 供应链安全检测
供应链安全检测主要聚焦第三方代码引入公司内部的安全性检测。
百度的产品代码托管在内部代码托管平台,因此供应链安全检测也应该围绕代码托管平台展开,除了在研发流程中嵌入新增代码检测以外,我们还针对存量的代码实现检测与工单追踪闭环,为第三方代码风险快速、有效收敛提供最便捷的通道。
整体检测架构为:
供应链检测系统中的第三方高危软件识别主要依托于指纹匹配技术,主要分为代码指纹识别与包管理解析两种。代码指纹识别类似于传统的正则匹配;包管理解析则是针对不同包管理文件,例如java的pom.xml、gradle,nodejs的package.json等,做语法解析,获取到引入的包名与版本号。代码指纹识别漏报率相对更高,包管理解析获取的包名通常为类库名,与第三方软件的通用名称存在差异,需要根据实际应用场景做进一步的适配和兼容。
第三方软件的漏洞被外界爆出后,攻击者可能在短时间内进行攻击,如果供应链检测无法做到快速响应,将会使得整个供应链安全检测的效果大大折扣,因此我们同步建设了实时指纹扫描与软件查询能力。通过打通线上工单系统,我们可以在分钟级完成漏洞代码定位与推送,并实现80% 以上代码库在一天内更新修复。以fastjson组件为例,在19年和20年的几次漏洞爆发中,我们在分钟级便完成大量使用fastjson组件的代码库定位与工单推送,并在天级的时间内推动业务代码完成修复,闭环效果十分明显。
- 安全编码规范检查
安全编码规范检查主要聚焦于百度内部生产的代码的安全性检测。
区别于于传统白盒安全扫描,安全编码规范检查治理白盒漏洞的思路是先通过制定相关的基于安全基础库的安全编码规范,要求业务摒弃一些危险的编码习惯,比如各种拼接写法、调用不安全的默认API等,使用安全SDK中的API实现相关的功能,从而降低写出漏洞的风险。
与供应链安全检测类似,百度安全编码规范检查也集成在公司内部研发工具链中。
在这种模式下,一条规范检查规则是这样的:
关于该治理措施和安全工具的构建,可以阅读:构建企业级研发安全编码规范
3.2.4 测试阶段
在测试阶段,我们主要嵌入了上线前安全基准测试,也就是市面上DevSecOps方案主要宣传的部分,即各种安全工具链的使用,作为产品上线前的最后一个兜底工作。
在百度,我们构建了:黑盒扫描(DAST)、白盒扫描(SAST)、灰盒扫描(IAST/FAST)、RASP等产品安全工具链,并将这些工具做到自动化程度极高,减少业务参与的难度,实现一次配置永久运行的效果。
值得注意的是,RASP技术(https://rasp.baidu.com)除了在遭受外部攻击时可以进行攻击识别,还可以从一些程序错误中有效识别出漏洞。因此在我们的实践中,RASP产品被大量部署在测试环境中,在对业务线完全透明的情况下,帮助业务线提前发现漏洞、风险。
3.2.5 上线&验证阶段
目前上线&验证阶段主要是要求业务线进行安全产品、安全防护能力的接入,主要涉及到:日志备份、线上版RASP、集团WAF等,确保产品线上运行时安全。
3.3 DevSecOps安全运营
当我们完成整个研发全链条的覆盖之后,后续的工作变得相对比较简单,可以将有限的人力投入到工具链安全能力建设、产品线DevSecOps定制化需求、重点业务场景安全解决方案制定与实施中。通过精细化的安全运营,确保DevSecOps得以准确、高质量的实施。
3.4 DevSecOps云原生场景探索
CNCF将云原生定义为致力于帮助企业在公有云、私有云和混合云等新型动态环境中构建与运行可弹性扩展应用的一种技术,包括容器、微服务以及不可变基础设施等。
相比于传统的基础架构模型,构建于云原生技术之上的研发模型能够实现应用弹性、可扩展部署,并且开发和交付也更加敏捷。但与此同时,由于基础软件自由引入,应用快速迭代,镜像的获取、容器的部署更加灵活,云原生产品研发过程中实际上具有更多潜在的安全风险。比如当基础镜像中引入了恶意组件或者高危组件这种场景,传统的产品安全措施与工具链很难对其进行风险治理与收敛。
因此,我们需要将DevSecOps与云原生深度结合,对云原生技术下构建的研发流程进行持续管控,更好地在研发链条中保护业务安全。
云原生时代下,我们在DevSecOps方案中增加了镜像安全扫描、安全分发、镜像签名与运行时监控等产品安全措施,这些与原有的应用层DevSecOps共同构成了一条完整的DevSecOps安全管控链路。镜像扫描可以通过配置是否阻断,来限制包含高危漏洞的镜像上线;安全分发可以保证镜像分发安全,而运行时监控则能针对线上容器危险操作、非法网络连接等进行阻断。具体的管控方案如下:
除了增加一些自动化的检查和监控以外,我们还在着力推动镜像仓库统一化、基础镜像标准化等,避免线上运行时环境过于分散,降低后期治理与管控成本。
除了上述内容,我们也在关注K8s等编排工具本身的安全性,宿主机上容器软件权限设置,以及内核安全等。
将DevSecOps应用到云原生化架构中,让安全与业务更加紧密地联系在一起,将会是云原生时代提升业务安全质量、降低业务安全风险和后期安全成本的最优解,也可能是唯一解。
四、DevSecOps建设收益
通过DevSecOps的落地,我们从过去仅在测试阶段检查转变为产品研发全流程的安全保障,进一步提升了研发效率、安全问题检出效率,降低了安全问题的修复成本,并提升了产品安全质量以及业务团队的安全素养。
此外,业务线在各个研发阶段都能看到安全相关的措施,安全措施和研发措施进行融合,增进安全协同,更能够让业务线意识到产品安全并不只是安全团队的事情,而是产品线、安全团队一起协同的结果,Sec和Dev、Ops一样,都是研发过程中必须要做的工作。
总的来说,通过DevSecOps的落地,我们获得了:
- 打造了覆盖研发全链条的产品安全框架,后续可以基于这个框架进行产品安全措施扩展,比如将隐私合规要求融入DevSecOps需求阶段中
- 提升了研发效率、安全问题检出效率,降低了修复成本
- 提升了产品安全质量以及业务团队的安全素养
- 大幅度降低线上漏洞风险,自DevSecOps落地后,线上风险得到了进一步收敛
五、文章总结
本文从传统SDL时代的痛点出发,阐述了我们建设DevSecOps的初衷,并分享了百度DevSecOps在各个研发阶段的建设、落地思路与安全实践,以及相关工具链打造经验。最后介绍了我们建设DevSecOps的相关收益与效果。
希望本文对读者有所帮助。