浅谈SDL与DevSecOps
/0x00 前言
这里仅谈谈个人对安全研发(SDL)和安全DevOps(DevSecOps)的理解及相关思考,但由于缺乏DevSecOps实践经验因此这块无法详细畅谈。
0x01 从企业的安全建设说起
任何企业都是以业务为重。当企业的业务发展受制于安全的时候,此时企业就会考虑往安全方面投入了。比如,某公司被脱裤导致用户信息泄露之后,才开始成立自己的安全部来推动安全保障业务。
在早期的一些投入安全整改的企业中,很多企业一般都是每年花钱来请乙方安全厂商来做渗透测试、安全评估扫描等等,然后看看安全报告、推动修补相应的漏洞就了事了。但是到后来发现,这样每年给钱乙方搞安全还不如自己招那么几个安全工程师成立自己的安全部来得划算。因此,“一个人的安全部”就在这样的一些背景下产生了。这样的安全部往往人不多,但是负责安全方面的工作却比较多,从渗透测试、漏洞认领复现、安全开发、与开发扯皮、应急响应、安全运维…等等,其中个人认为于企业而言性价比最高的当然就是安全开发,企业如果购买安全厂商产品的话成本是很高的,但是如果自己招几个安全工程师搞下安全开发、搞一些如WAF、漏洞扫描器、IDS和IPS等产品,这就省了很多成本,到后期安全产品成熟了、也就变成了养那么几个安全工程师或者无须有的事情了。
当然,对于大厂而言,往往都会组建人数不少的安全部甚至每个产品线都组建自己的安全部来负责自己的产品安全,侧重点在于挖洞和修洞这两块。但是到后面,随着业务的发展,版本迭代越来越迅速,软件开发模型也变换甚多。此时,企业如果还只是纯粹地做渗透测试和安全风险评估,必然无法保障如此多版本的安全性,同时由于挖出的漏洞已处于产品“定型”阶段、导致漏洞的修复成本会非常高,这时国内企业又寻求新的变更点、学习微软的SDL,即将安全前置、使产品开发的每个阶段都融入安全活动、提高产品安全性并大大降低安全问题导致的修复成本。
0x02 SDL
SDL简介
SDL全称Security Development Lifecycle,即安全开发生命周期,是由微软提出并应用的一个帮助开发人员构建更安全的软件和解决安全合规要求的同时降低开发成本的软件开发过程。
SDL的核心理念就是将安全考虑集成在软件开发的每一个阶段:需求分析、设计、编码、测试和维护。从需求、设计到发布产品的每一个阶段每都增加了相应的安全活动,以减少软件中漏洞的数量并将安全缺陷降低到最小程度。
SDL、SDLC和S-SDLC
SDL:Security Development Lifecycle,安全开发生命周期;
SDLC:Software Development Life Cycle,软件开发生命周期;
S-SDLC:Secure Software Development Life Cycle,安全软件开发生命周期,是由开源Web安全组织OWASP推出的一个项目,它跟SDL的区别是它更关注的是SDL的落地化;
SDL相关人员角色
微软SDL中给出如下角色定义:
- 评析者/顾问角色:这些角色的任务是对项目安全和隐私进行监督,有权接受或拒绝项目团队的安全和隐私计划。
- 安全顾问/隐私顾问。这些角色由项目团队外部的主题专家 (SME) 担任。该角色可以由组织中专门进行此类评析的独立集中小组中的合格成员担任,也可以由组织外部的专家担任。为此任务选择的人员必须担任两个子角色:
- 审计官。此角色必须监控软件开发过程的每个阶段,并证明每个安全要求的成功实现。审计官必须能够自主证明过程是否符合安全和隐私要求方面的要求,而不受项目团队的干扰。
- 专家。为顾问角色选择的人员必须在安全方面拥有可靠的相关专业知识。
- 顾问角色组合。如果可以确认某人具有合适的技能和经验,则安全顾问的角色可以与隐私顾问的角色合二为一。
- 安全顾问/隐私顾问。这些角色由项目团队外部的主题专家 (SME) 担任。该角色可以由组织中专门进行此类评析的独立集中小组中的合格成员担任,也可以由组织外部的专家担任。为此任务选择的人员必须担任两个子角色:
- 团队负责人。团队负责人角色应由项目团队的主题专家担任。这些角色负责协商、接受和跟踪最低安全和隐私要求,并在软件开发项目过程中与顾问和决策者保持通畅的沟通渠道。
- 安全负责人/隐私负责人。此角色(一人或多人)不仅负责确保软件发布解决了所有安全问题,还负责协调和跟踪项目的安全问题。此角色还负责向安全顾问和项目团队的其他相关方(例如,开发和测试负责人)报告情况。
- 角色组合。与安全和隐私顾问角色一样,如果可以确认某人具有合适的技能和经验,则可以由一人承担负责人角色的职责。
SDL安全活动
从Microsoft SDL看起,这是一组必需的安全活动,这些活动的执行顺序与其显示顺序相同,按传统软件开发生命周期 (SDLC) 的阶段分组:
如上图列出的是SDL中必须进行的安全活动。下面来看下各个阶段的安全活动。
必须的安全活动
SDL执行前:安全培训
在SDL执行之前,需要给研发团队进行相关的安全培训,包括但不限于以下内容。当然,个人认为对产品线研发团队的安全培训并不只是限于SDL执行之前、而是针对各个阶段都要进行。
- 安全设计,包括以下主题:
- 减小攻击面
- 深度防御
- 最小权限原则
- 安全默认设置
- 威胁建模,包括以下主题:
- 威胁建模概述
- 威胁模型的设计意义
- 基于威胁模型的编码约束
- 安全编码,包括以下主题:
- 缓冲区溢出(对于使用 C 和 C++ 的应用程序)
- 整数算法错误(对于使用 C 和 C++ 的应用程序)
- 跨站点脚本(对于托管代码和 Web 应用程序)
- SQL 注入(对于托管代码和 Web 应用程序)
- 弱加密安全测试,包括以下主题:
- 安全测试与功能测试之间的区别
- 风险评估
- 安全测试方法
- 隐私,包括以下主题:
- 隐私敏感数据的类型
- 隐私设计最佳实践
- 风险评估
- 隐私开发最佳实践
- 隐私测试最佳实践
第一阶段:要求
本阶段主要包括3个SDL实践:
- 安全要求:“预先”考虑安全和隐私是开发安全系统过程的基础环节。为软件项目定义信任度要求的最佳时间是在初始计划阶段。尽早定义要求有助于开发团队确定关键里程碑和交付成果,并使集成安全和隐私的过程尽量不影响到计划和安排。对安全和隐私要求的分析在项目初期执行,所做工作涉及为设计在计划运行环境中运行的应用程序确定最低安全要求,并确立和部署安全漏洞/工作项跟踪系统。
- 质量门/Bug栏:用于确立安全和隐私质量的最低可接受级别。
- 安全和隐私风险评估:安全风险评估 (SRA) 和隐私风险评估 (PRA) 是必需的过程,用于确定软件中需要深入评析的功能环节。这些评估必须包括以下信息:
- (安全)项目的哪些部分在发布前需要威胁模型?
- (安全)项目的哪些部分在发布前需要进行安全设计评析?
- (安全)项目的哪些部分(如果有)需要由不属于项目团队且双方认可的小组进行渗透测试?
- (安全)是否存在安全顾问认为有必要增加的测试或分析要求以缓解安全风险?
- (安全)模糊测试要求的具体范围是什么?
- (隐私)隐私影响评级如何?
第二阶段:设计
SDL安全设计的6个核心原则:
- Attack Surface Reduction(攻击面最小化)
- Basic Privacy(基本隐私)
- Least Privilege(权限最小化)
- Secure Defaults(默认安全)
- Defense in Depth(纵深防御)
- Threat Modeling(威胁建模)
第三阶段:实施
本阶段主要包括3个SDL实践:
- 使用批准的工具:所有开发团队都应定义并发布获准工具及其关联安全检查的列表,如编译器/链接器选项和警告。此列表应由项目团队的安全顾问进行批准。一般而言,开发团队应尽量使用最新版本的获准工具,以利用新的安全分析功能和保护措施。
- 弃用不安全的函数:许多常用函数和 API 在当前威胁环境下并不安全。项目团队应分析将与软件开发项目结合使用的所有函数和 API,并禁用确定为不安全的函数和 API。确定禁用列表之后,项目团队应使用头文件(如 banned.h 和 strsafe.h)、较新的编译器或代码扫描工具来检查代码(在适当情况下还包括旧代码)中是否存在禁用函数,并使用更安全的备选函数替代这些禁用函数。
- 静态代码分析:项目团队应对源代码执行静态分析。源代码静态分析为安全代码评析提供了伸缩性,可以帮助确保对安全代码策略的遵守。静态代码分析本身通常不足以替代人工代码评析。安全团队和安全顾问应了解静态分析工具的优点和缺点,并准备好根据需要为静态分析工具辅以其他工具或人工评析。
第四阶段:验证
本阶段主要包括3个SDL实践:
- 动态程序分析:为确保程序功能按照设计方式工作,有必要对软件程序进行运行时验证。此验证任务应指定一些工具,用以监控应用程序行为是否存在内存损坏、用户权限问题以及其他重要安全问题。SDL 过程使用运行时工具(如 AppVerifier)以及其他方法(如模糊测试)来实现所需级别的安全测试覆盖率。
- 模糊测试:模糊测试是一种专门形式的动态分析,它通过故意向应用程序引入不良格式或随机数据诱发程序故障。模糊测试策略的制定以应用程序的预期用途以及应用程序的功能和设计规范为基础。安全顾问可能要求进行额外的模糊测试或扩大模糊测试的范围和增加持续时间。
- 威胁模型和攻击面评审:应用程序经常会严重偏离在软件开发项目要求和设计阶段所制定的功能和设计规范。因此,在给定应用程序完成编码后重新评析其威胁模型和攻击面度量是非常重要的。此评析可确保考虑到对系统设计或实现方面所做的全部更改,并确保因这些更改而形成的所有新攻击平台得以评析和缓解。
第五阶段:发布
本阶段主要包括3个SDL实践:
- 事件响应计划:受SD 要求约束的每个软件发布都必须包含事件响应计划。即使在发布时不包含任何已知漏洞的程序也可能面临日后新出现的威胁。事件响应计划应包括:
- 单独指定的可持续工程 (SE) 团队;或者,如果团队太小以至于无法拥有 SE 资源,则应制定紧急响应计划 (ERP),在该计划中确定相应的工程、市场营销、通信和管理人员充当发生安全紧急事件时的首要联系点。
- 与决策机构的电话联系(7 x 24 随时可用)。
- 针对从组织中其他小组继承的代码的安全维护计划。
- 针对获得许可的第三方代码的安全维护计划,包括文件名、版本、源代码、第三方联系信息以及要更改的合同许可(如果适用)。
- 最终安全评审:最终安全评析 (FSR) 是在发布之前仔细检查对软件应用程序执行的所有安全活动。FSR 由安全顾问在普通开发人员以及安全和隐私团队负责人的协助下执行。FSR 不是“渗透和修补”活动,也不是用于执行以前忽略或忘记的安全活动的时机。FSR 通常要根据以前确定的质量门或 Bug 栏检查威胁模型、异常请求、工具输出和性能。
- 发布/存档:指派负责发布事宜的安全顾问必须证明(使用 FSR 和其他数据)项目团队已满足安全要求。此外,必须对所有相关信息和数据进行存档,以便可以对软件进行发布后维护。这些信息和数据包括所有规范、源代码、二进制文件、专用符号、威胁模型、文档、紧急响应计划、任何第三方软件的许可证和服务条款以及执行发布后维护任务所需的任何其他数据。
发布后:响应
产品在发布后的安全应急响应是必须要做的。
可选的安全活动
可选的安全活动是需要专业的安全团队来完成的
代码审计
尽管前面有静态代码分析的实践,但是都是基于使用静态代码扫描工具扫描的形式来进行的,其中可能会存在更多的安全代码问题比如业务逻辑漏洞、0day等是工具扫描不出来的,此时就需要专业的安全团队进行人工代码审计,从而进一步提高产品的安全性。
渗透测试
渗透测试通过和代码审计一起完成的,侧重在模拟外部黑客来从外部进行黑/灰盒渗透测试,以黑客的视角来发现产品安全问题。
相似产品的漏洞分析
专业安全团队通过分析友商或其他相似产品历史出现过的漏洞,再审计当前产品是否存在相似的漏洞,借助其他产品的经验来修补已知的安全问题。
Threat Modeling(威胁建模)
威胁建模是SDL流程中的核心组成部分,是一种可以用来帮助开发人员与SDL工程师提前识别可能影响到应用的威胁、攻击、漏洞和对策。使用威胁建模来完成产品的设计,可以有效满足企业的安全目标并降低安全风险。
微软中提到威胁建模的5个关键步骤如下:
- 定义安全需求
- 创建应用图解
- 识别威胁
- 缓解威胁
- 验证威胁是否已缓解
在进行威胁建模分析上,微软还提供了专用于威胁建模的工具Microsoft Threat Modeling Tool,工具下载地址:https://aka.ms/threatmodelingtool
威胁建模也是有方法的,就是STRIDE方法。
STRIDE
STRIDE威胁建模是由微软提出的一种威胁建模方法,该方法将威胁类型分为Spoofing(仿冒)、Tampering(篡改)、Repudiation(抵赖)、Information Disclosure(信息泄漏)、Denial of Service(拒绝服务)和 Elevation of Privilege(权限提升)。STRIDE威胁模型几乎可以涵盖目前绝大部分安全问题。
相关概念解释如下表:
威胁 | 定义 | 对应的安全属性 |
---|---|---|
Spoofing | 冒充他人身份 | 认证 |
Tampering | 修改数据或代码 | 完整性 |
Repudiation | 否认做过的事 | 不可抵赖性 |
Information Disclosure | 机密信息泄露 | 机密性 |
Denial of Service | 拒绝服务 | 可用性 |
Elevation of Privilege | 未经授权获得许可 | 授权 |
STRIDE威胁建模流程和前面介绍的一样:
- 绘制数据流图
- 识别威胁
- 提出缓解措施
- 安全验证
数据流图
数据流图(Data Flow Diagrams)包含外部实体(External Entity)、处理过程(Process)、数据流(Data Flow)、数据存储(Data Store):
安全人员与系统架构师及设计人员沟通,了解设计详情并画出数据流图后还需要标注信任边界(Trust Boundary),当然也可以通过赋能架构师与开发人员来自行画出数据流图让安全人员评审。
网上一个简单的Web应用数据流图如下,注意要用红色虚拟隔离出信任边界:
为了规范,是需要用到上面提到的Microsoft Threat Modeling Tool这个工具来描绘数据流图的,具体绘图细节这里不多说,看个网上的工具范例:
识别威胁
STRIDE威胁建模方法已经明确了每个数据流图元素具有不同的威胁,其中外部实体只有仿冒(S)、抵赖(R)威胁,数据流只有篡改(T)、信息泄露(I)、拒绝服务(D)威胁,处理过程有所有六种(STRIDE)威胁,存储过程有篡改(T)、信息泄露(I)、拒绝服务(D)威胁,但如果是日志类型存储则还有抵赖(R)威胁。具体可以对照如下表格进行威胁识别:
元素 | S | T | R | I | D | E |
---|---|---|---|---|---|---|
外部实体 | √ | √ | ||||
处理过程 | √ | √ | √ | √ | √ | √ |
数据存储 | √ | ? | √ | √ | ||
数据流 | √ | √ | √ |
缓解措施
识别到威胁之后,就要针对某一项危险提出对应的缓解措施。注意,这里之所以是缓解而不是消除,是因为大多数时候由于业务功能导致很多威胁是无法根除的。
微软对于常用的威胁给出了其常用的标准缓解措施,并在具体实施时已将常用的缓解方案及措施集成为独立的解决方案或者代码模块。可以方便同类应用直接使用。
威胁类型 | 缓解措施 | 技术方案 |
---|---|---|
仿冒(S) | 认证 | Kerberos认证PKI系统如SSL / TLS证书数字签名 |
篡改(T) | 完整性保护 | 访问控制完整性校验 |
抵赖(R) | 日志审计 | 强认证安全日志、审计 |
信息泄露(I) | 保密性 | 加密访问控制列表 |
拒绝服务(D) | 可用性 | 访问控制列表过滤热备份 |
权限提升(E) | 授权认证 | 输入校验用户组管理访问控制列表 |
安全验证
在威胁建模完成后,需要对整个过程进行回顾,不仅要确认缓解措施是否能够真正缓解潜在威胁,同时验证数据流图是否符合设计,代码实现是否符合预期设计,所有的威胁是否都有相应的缓解措施。最后将威胁建模报告留存档案,作为后续迭代开发、增量开发时威胁建模的参考依据。
0x03 DevSecOps
软件开发模型的演进
在说到DevSecOps之前就必须先了解下软件开发模型的主要演进过程。
瀑布模型
在传统的软件开发模型中,最常用的就是瀑布模型(Waterfall Model)。
瀑布模型是严格把软件项目的开发分隔成各个开发阶段,使用里程碑的方式,严格定义了各开发阶段的输入和输出。如果达不到要求的输出,下一阶段的工作就不展开。
敏捷开发
传统的瀑布模型是没法满足日新月异的业务需求变化的,此时就出现了敏捷开发模型。
敏捷软件开发(Agile software development),又称敏捷开发,是一种从1990年代开始逐渐引起广泛关注的一些新型软件开发方法,是一种应对快速变化的需求的一种软件开发能力。它们的具体名称、理念、过程、术语都不尽相同,相对于“非敏捷”,更强调程序员团队与业务专家之间的紧密协作、面对面的沟通(认为比书面的文档更有效)、频繁交付新的软件版本、紧凑而自我组织型的团队、能够很好地适应需求变化的代码编写和团队组织方法,也更注重软件开发过程中人的作用。
敏捷开发的核心是迭代。
如图,可以明显看到两者的区别:
可以看到,敏捷开发是将分析、设计、编码和测试等阶段作为迭代的部分来进行迭代开发的。但是,这只是开发流程的快速优化,运维流程并不在其中,也就是说在瀑布或敏捷模型中都是要开发流程走完才能到达运维人员负责后续的运维阶段(Operations)的工作,这就导致业务不能提供更快速稳定的交付了。此时,DevOps应运而生。
DevOps
DevOps简介
DevOps并无权威官方的描述定义,这里引用维基百科的:
DevOps(Development和Operations的组合词)是一种重视“软件开发人员(Dev)”和“IT运维技术人员(Ops)”之间沟通合作的文化、运动或惯例。透过自动化“软件交付”和“架构变更”的流程,来使得构建、测试、发布软件能够更加地快捷、频繁和可靠。
可以把DevOps看作开发(软件工程)、技术运营和质量保障(QA)三者的交集:
DevOps强调的是高效组织团队之间如何通过自动化的工具协作和沟通来完成软件的生命周期管理,从而更快、更频繁地交付更稳定的软件。
DevOps生命周期
DevOps的生命周期如图,是个循环的、开发与运维各阶段活动集成的:
概念对比
这里引用腾讯安全云鼎实验室的图,一目了然这几种软件开发模型之间的区别:
如上图所示,部署操作并不是等到最后才进行、而是和开发测试操作一同迭代进行的。
DevOps做法
DevOps做法如下:
- 持续集成和持续交付(CI/CD)
- 版本控制
- 敏捷软件开发
- 基础结构即代码
- 配置管理
- 持续监视
给SDL带来的挑战
SDL是将安全考虑集成在软件开发的每一个阶段、为每一个开发阶段添加对应的安全活动,是基于产品发布上线前进行的一系列安全活动,这种模式在瀑布模型和敏捷开发中是适用的。但是到了DevOps后,SDL就显得相形见绌了,主要在于DevOps的快速持续集成、持续交付、持续部署等特性和SDL执行的流水线式缓慢过程是互相冲突的,这就使得安全拖慢了DevOps。
基于此,Gartner在2012年就提出了DevSecOps来解决安全DevOps问题。
DevSecOps简介
DevSecOps,全称Development Security Operations,是一套有Gartner提出的基于DevOps体系的全新IT安全实践战略框架,是一种旨在将安全性嵌入DevOps链条中的每个部分新方法,它有助于在开发过程早期而不是产品发布后识别安全问题,目标是让每个人对信息安全负责,而不仅仅是安全部门。
相比于SDL,DevSecOps已不只是关注开发阶段的安全,而是需要将安全嵌入到开发和运维的整个DevOps的生命周期中。
在之前,安全只是特定团队的职责,是在开发的最后阶段才会介入的:
这种方式显然会拖累DecOps的高效性,因此DevSecOps提出的概念就是,安全是整个IT团队的共同职责,人人为安全负责,人人参与安全:
广义上的DevOps的建设会包含:人、流程、工具等多方面内容。
因此,DevSecOps 意味着从一开始就要考虑应用和基础架构的安全性;同时还要让某些安全网关实现自动化,以防止 DevOps 工作流程变慢。选择合适的工具来持续集成安全防护(比如在集成开发环境(IDE)中集成安全防护功能)有助于实现这些目标。但是高效的 DevOps 安防需要的不仅是新工具。它更需要整个公司实现 DevOps 文化变革,从而尽早集成安全团队的工作。
DevSecOps架构图
DevSecOps架构图如下:
从SDL到DevSecOps的变化
个人理解,DevSecOps就是SDL针对DecOps的快速优化版,两者并非是完全不同的东西,而是针对迭代快速的业务进行的优化:
- 安全文化普及,强调每个人都对安全负责;
- 更多的自动化实现,摒弃SDL中过多的人工参与;
- 融入整个开发与运维流程中,而不是只嵌入开发流程;
- 使得安全活动更为前置;
DevSecOps实践
这块尚未接触,写了也是纸上谈兵,后续如果接触到DevSecOps实践这块再补充。