2.5万字读懂企业DevSecOps全实践

01/24 19:06
阅读数 2.5K

本文译自Securosis网站Adrian Lane的系列博客文章,内容包括: 

  • 基本原则

  • 安全人员如何与开发协同工作

  • 安全测试集成

  • 构建安全工具链

  • 安全计划

  • 安全人员在 DevOps 中的作用

一、基本原则

1.1 导语

DevOps 是一个操作框架,通过自动化来促进软件的一致性和标准化。通过打破不同开发团队之间的障碍,同时通过优先考虑使软件开发更快更容易的事情,该框架帮助解决了围绕集成、测试、打包和部署的许多噩梦般的开发问题。

DevSecOps是将安全团队和安全工具直接集成到软件开发生命周期中,利用 DevOps 的自动化和效率,确保每个构建周期都进行应用程序安全测试。这促进了安全性、一致性,并确保安全性与其他质量指标或特性同样重要。自动化的安全性测试,就像自动化的应用程序构建和部署一样,必须与基础设施的其余部分一起组装。

这就是问题所在。软件开发人员传统上并不支持安全性。这并不是因为他们不关心安全问题,而是因为他们被鼓励去关注新特性和功能的交付。DevOps 正在改变自动化构建过程的优先级,使它们更快、更简单并且更一致。

但是,这并不意味着他们会特意加入安全或安全工具。这是因为安全工具不容易与开发工具和流程很好地集成,我们经常会发现大量队列堆积,并且以开发为中心的过滤器难以帮助优先安全工作。更糟糕的是,安全平台——以及推荐它们的安全专业人员——很难使用,甚至无法提供 API 支持来提供集成。

另一方面在于安全团队,他们害怕自动化的软件过程,经常会问“我们如何控制开发”这样的问题。这一问题的本质既忽略了 DevSecOps 的精神,也忽略了开发组织为使每个软件版本更快、更高效和更一致所做的努力。对于安全团队来说,应对软件开发中发生的变化,并扩展他们相对较小的组织的唯一方法,就是变得和开发团队一样敏捷,并且拥抱自动化。

1.2 为什么我要写这篇文章?

我们通常讨论我们做研究背后的动机,以帮助读者理解我们的目标和希望传达的内容。当我们更新一份研究报告时,情况就更加复杂了,因为它有助于我们聚焦最近行业的变化,这些变化导致旧的论文在描述最近的趋势方面存在不准确或不足的问题。由于 DevOps 和 DevSecOps 选项在近四年已经相当成熟,所以,关于这一方面我们有很多要谈的。

这项工作将是对我们2015年关于将安全构建到 DevOps 中的研究工作的重大改写,包括围绕安全团队询问的关于 DevSecOps 的常见问题的重大增补,以及对集成工具和方法的彻底更新。

这篇研究论文的大部分内容将反映的是2017年以来财富2000强公司的200多个安全团队的400多次谈话。因此,我们将包括众多从这些对话中衍生出来的讨论要点。由于 DevOps 已经存在了很多年,我们将不过多讨论什么是 DevSecOps 或者它是如何对我们有益的,更多的是关于如何组合一个 DevSecOps 程序的务实的内容。

现在,让我们开始改变!

1.3 不同的焦点,不同的价值

有大量新的调查和研究论文可用,其中一些是非常好的。还有更多的会议和在线资源涌现出来,资源多到我都数不过来了。例如,Veracode 最近发布了他们的软件安全状态(SoSS)报告的最新版本,这份报告是一个大部头读物,带有大量的数据和观察。关键的要点是 DevSecOps 团队使用的灵活性和自动化提供了明显的安全优势,包括更快的修补周期,更短的缺陷持续时间,更快的技术债务减少,以及更容易的扫描意味着更快的问题识别。

最近发布的2019年软件供应链状态报告显示,团队表示,模范项目团队利用 DevOps 原则大大降低了代码部署失败率,补救漏洞的时间只有平均水平的一半。

我们还有像DevOps全天的活动,数以百计的 DevOps 从业者在这里分享关于文化转型、持续集成 / 持续部署(CI/CD)技术、SRE以及 DevSecOps 的故事。

所有这些都很棒,并且提供了一系列定性和定量的数据来说明为什么 DevOps 可行,以及从业人员是如何演变他们的程序的。

这不是这篇文章的主题。这些资源并没有解决我每周都被问到的问题。

注意,本文是关于如何整合一个全面的 DevSecOps 项目。因为我们总是被问到“我如何把一个 DevSecOps 项目组合在一起? ” 以及“安全性与 DevOps 有什么关系? ” 。他们不是在寻找正当理由,也不是在寻找关于细微差别的故事来解决具体的障碍。他们需要一个与同行组织保持一致的安全程序,并拥护“安全最佳实践”。这些受众绝大多数是安全和 IT 从业者,很大程度上被开发团队所遗忘,他们至少接受了敏捷概念,如果不是完全接受 DevOps 的话。面临的挑战是理解开发试图完成什么,以某种方式与这些团队集成,并弄清楚如何利用自动化安全测试,使其至少像开发团队一样敏捷。

1.4 DevOps vs DevSecOps

这就引出了另一个有争议的话题,以及为什么这项研究与众不同: DevSecOps 这个名字。我们的论点是,鉴于在这个问题上缺乏成熟与理解,调用安全性(“ DevSecOps”中的“ Sec”)是必要的。

换句话说,完全支持DevOps这一运动的实践者会告诉你,没有理由在 DevOps 中加入 Sec,因为安全只是其中一个因素。DevOps 的理想是打破单个团队之间的隔阂(例如: 架构、开发、 IT、安全和 QA) ,以更好地促进团队合作,更好地激励每个团队成员朝着相同的目标前进。

如果安全性只是融合在构建和交付软件的总体工作中的一组技能,那么我们就没有理由称之为安全保证。

从哲学层面讲,这些支持者是对的。但实际上,我们还没有到那个地步。也许开发人员能够接受这个想法 ---- 他们其实并不擅长促成团队集成。当然,安全是可以自由参与的,但这取决于他们了解在哪里可以集成,并通常要求将他们可能不具备的技能带到聚会上。这是被动攻击型的团队建设!

自动化的安全性测试,就像自动化的应用程序构建和部署一样,需要时间和技能来构建。在我们与客户典型的安全会议中,开发人员并不怎么参与。因此分歧仍然存在,安全团队和通常有几十到几百个分散的开发团队之间几乎没有交流。当开发人员在场时,他们声明安全团队可以创建脚本,将安全测试集成到构建服务器中; 他们可以编写安全策略; 安全可以将安全分析工具与故障检测以及几行 python 代码的度量结合在一起。

毕竟,许多 IT 从业者正在学习为组态管理编写脚本,并构建模板来定义基础设施部署,那么为什么不提供安全性呢?这完全忽略了一个事实,即很少有安全从业人员能够在这个级别编写代码。更糟糕的是,与我们交谈的大多数公司的开发人员与安全从业人员的比例约为100:1,而且根本没有办法在所有开发项目中扩展安全资源。

许多安全专家还处在理解DevOps的早期阶段,以及开发人员在过去十年中为了变得更加敏捷而采用的各种方法。安全确实落后于形势,而且似乎现有的大部分研究(上文提到的)并不是为了解决安全的引入和整合问题。

最后,我们选择使用 DevSecOps 名称还有一个非常重要的原因: 代码安全方面的安全工作与基础设施和支持组件的安全工作非常不同。用于验证应用程序代码的安全性检查是安全的(即: DevSec) ,但与使用的工具和过程不同,它们用于验证支持基础架构(即: SecOps)是安全的。这是两个不同的规程,具有不同的工具和方法,应该作为单独的工作进行讨论。

1.5 常见问题

我们检查了过去三年所有的电话记录,并记录了我们被问到的问题。下面的列表是最常见的问题,按问题被问到的频率排序如下。

  • 我们希望将安全性测试集成到开发管道中,并将从静态分析开始。我们该怎么做?

  • 我们如何根据自动化、 CI/CD 和 DevOps 构建应用程序安全策略?

  • 如何开始构建一个应用程序策略? 我应该遵循什么应用程序安全标准?

  • 开发部门每天都在向生产环境发布代码。我们如何控制开发?我们真的能够改变开发人员的行为吗?

  • 引入 DevSecOps 的最佳方式是什么?我该从哪里开始呢?最基本的部分是什么?

  • 现状有些是瀑布式的,有些是敏捷的,有些是 DevOps 的时候,我们如何让不同的单位采用同一个流程(不同的团队做事情的方式不同) ?

  • 我们(安全)应该如何与开发人员一起工作?

  • 我们理解左移,但是这些工具有效吗?你建议从哪些工具开始呢?

这些问题都有一些共同的线索:它们都来自至少有一些团队DevOps实践已经开展的公司,安全部门对 DevOps 的意图有一些了解,但是安全都是从零开始的。即使已经在开发管道中内置了安全测试的团队也在为每个工具提供的价值、开发人员对于误报的抵触、如何与开发人员合作或者如何在多个开发团队之间进行扩展以保持一致性而苦苦挣扎。

我们发现,在调用和约定期间,安全人员与开发人员接受 DevOps 的原因并不完全一致,并且错过了工作的重点,这就是为什么它们通常不同步的原因。

以下是我们提出的安全性问题清单,安全团队应该问这些问题,但是没有解决。

  • 我们在文化上和操作上如何适应 DevSecOps?

  • 我们该如何使开发和开发实践具有可见性?

  • 我们如何知道变化是有效的? 我们应该收集和监控哪些指标?

  • 我们该如何支持开发部门?

  • 我们需要知道如何编码吗?

在本文中,我们将讨论这两个问题列表。接下来,我们将简要介绍 DevOps 原则和安全在 DevOps 中的作用。

二、安全如何与研发协同工作

考虑到 DevOps 对于大多数读者来说是全新的概念,所以在第一节章我们分享了一个关于基本原则的讨论,以及 DevOps 是如何帮助解决软件交付中常见的许多问题的。你可以从中找到想要了解的更详细的背景资料。

出于本章的目的,我们将讨论一些与安全团队集成和使用 DevOps 原则进行安全测试直接相关的原则。这些概念为解决我们在第一部分中提出的问题奠定了基础,在我们讨论 DevOps 环境中的安全工具和方法时,读者需要理解这些概念。

2.1 DevOps 与安全

2.1.1 构建安全性

构建安全性,听起来是一个可怕的事实,但是在代码开发过程中广泛使用应用程序安全性技术,相对来说还是较新的事情。当然,对这个领域的研究已经有几十年的历史了,但是应用程序安全性更多地是通过网络或应用程序防火墙加固的,而不是嵌入到代码本身。

安全产品供应商发现,在应用程序之外理解应用程序请求做安全检测并阻止攻击是非常困难的。在可能的情况下,修复易受攻击的代码并关闭攻击载体要有效得多。附加工具正在变得越来越好用——有些工作是在应用程序上下文中进行的——但是如果可能的话,最好能在代码中解决这些问题。

构建安全性的一个核心概念是“左移” ,或者是我们在软件开发生命周期(SDLC)中更早地集成安全测试的想法——这些阶段按照从左到右的顺序通常可以分为设计、开发、测试、预生产和生产。

从本质上讲,我们将更多的资源从最右端的生产进行左移,将更多的资源投入到设计、测试和开发阶段。这些思想诞生于精益生产,Kaizen 和 Deming 的原则,已被证明是有效的,但通常应用于制造行业。DevOps 已经在软件开发领域得到了推广和应用,证明我们可以通过在研发过程的早期将缺陷安全检测左移来实现以较低的成本提高安全性。

2.1.2 自动化

对于我们谈到的大多数公司来说,自动化是成功的关键之一,以至于工程团队常常将 DevOps 和自动化等同起来。现实问题是随着 DevOps 而来的文化和组织上的变化同样重要,只是自动化有时候最能量化收益。

自动化为相关各方带来了速度、一致性和效率。和敏捷开发一样,DevOps 的目标是做得更少、更好、更快。软件发布更有规律,代码变更更少。更少的工作意味着更好的专注,每次发布的目的更明确,就能导致更少的错误。这也意味着在发生错误时更容易回滚。自动化帮助人们以较少的实际操作完成了工作,但是由于自动化软件每次都做完全相同的事情,所以,一致性是最为明显的一个好处。

首先应用自动化的地方是应用程序构建服务器,自动化的好处在这里最为明显。构建服务器(例如: Bamboo,Jenkins,) ,通常称为持续集成(CI)服务器,在代码更改时自动构建一个应用程序——甚至可能是整个应用程序堆栈。一旦构建了应用程序,这些平台还可能启动 QA 和安全测试,将失败的构建反馈给开发团队。自动化有利于软件生产的其他方面,包括报告、度量、质量保证和发布管理,但是安全测试所带来的好处则是我们在这项研究中所关注的。

从一开始来看,调用安全测试工具代替手动运行测试所带来的好处并不是很多。这种观点忽略了自动化安全测试的基本好处。自动化是我们如何确保软件的每次更新都包括安全测试,以确保一致性。自动化可以帮助我们避免重复的或者完全透明的人工任务中常见的错误和遗漏。但最重要的是,由于开发人员通常比安全团队多100倍,自动化是扩大安全覆盖范围的关键因素,而无需扩大安全人员的规模。

2.1.3 论一个团队的重要性

一个关键的 DevOps 原则是打破孤岛,在开发人员和支持 QA、 IT、安全和其他团队之间有更好的合作。我们经常听到这样的想法,这听起来很老套,但事实上在软件开发中很少有人能真正做出改变来实现这个想法。大多数以 DevOps 为中心的公司正在改变开发团队的组成,以及包括来自所有学科的科代表; 这意味着每个团队都有一个了解一点安全或者是代表安全利益的人,即使是在一个小团队中。

对于那些做到这一点的人来说,他们不仅意识到了更好的沟通所带来的好处,还意识到了目标和激励的真正一致性。孤立的开发模式可以激励开发人员编写出新的特性。孤立的质量保证是为了获得各种测试的代码覆盖率。当团队中的每个人都对新软件的成功发布负责时,优先级和行为的改变就会发生变化。

对于我们采访过的许多公司来说,这个问题依然存在。我们接触过的大多数公司规模都很大,有数百个开发团队分布在不同的国家,其中一些是第三方(即外部)咨询公司。所有这些团队都很难保持一致性,更加难以获得普遍参与。

管理结构的建立使开发经理管理开发人员,而不是 IT 运维人员。用于特性跟踪、故障排除和资源分配的管理工具是面向孤岛结构的。许多领先的安全工具被设置为用于分析和向安全专业人员报告缺陷,而不是向解决问题的开发人员或 IT 人员报告。进度仍然是通过功能输出和代码覆盖率来衡量的,并且相应地发放奖金。

这里的要点是,如果不对支持安全的系统和结构进行一些改变,这种文化变革和由此产生的巨大利益是无法实现的。这是一个非常艰难的调整,各种各样的管理者都希望实施策略,就好像他们拥有完全的监督权一样,可是他们忽略了一点,那就是他们也需要与他们的同行一起采用‘一个团队'的方法来有效地进行改革。

2.1.4 安全从业人员及应用程序安全

为什么安全人员要与 DevSecOps,甚至是一般的应用程序安全做斗争,因为他们没有软件开发的背景。大多数安全从业人员来自网络安全背景,我们谈到的许多 CISO 更加注重风险和合规性,因此普遍缺乏对软件开发的理解。

缺乏开发工具和过程的知识,以及开发人员试图克服的常见挑战,就意味着安全团队很少理解为什么自动化构建服务器、中央代码库、容器、敏捷和 DevOps 能在很短的时间内被广泛采用。在这里,我们将讨论开发实践中的一些变化驱动因素,以及安全团队在尝试处理应用程序安全性时需要理解的关键领域。

  • 对过程的认识 

我们在这里不是要教各位开发过程中的细微差别,而是要指出过程变化的原因: 速度。瀑布法、螺旋法、原型演进法、极限编程、敏捷开发以及Scrum敏捷开发都是在过去20年中形成的过程变体。每一个都有相同的目标: 减少复杂性(即: 简化需求)和加速软件交付。

当你明白在过去的20年里我们在实现如何构建软件的大多数改变都是为了实现这两个目标时,你就会开始明白这个过程本身并不重要; 更快、更好的交付软件才是最重要的目标。每日例会、两周一次的软件交付(例如: Sprints)、看板(Kanban)、敏捷、测试驱动开发和自动化构建服务器都是提升技术水平的工具。

因此,对于安全专业人员来说,理解安全测试和策略应该包含这些相同的理念是至关重要的。最后,DevOps 是独立于过程的; 你可以接受 DevOps,并且仍然保留一个瀑布式的过程,不过 DevOps 更适合敏捷开发。

  • 对工具的认识

软件开发利用许多工具来管理代码和过程。其中,对安全性最重要的两个是代码存储库和代码构建工具。像 Git 这样的存储库实质上是管理应用程序代码,为开发人员提供一个共享位置来存储代码、跟踪版本以及变更代码。其他的,如 Docker Registry,则专门用于容器。

这些工具对于开发人员管理他们正在构建的代码至关重要,但对于安全性也很重要,因为它提供了一个可以检查代码的地方。构建像 Jenkins 和 Bamboo 这样的服务器来自动化代码的构建、测试和交付。但是,它们通常用于完整的应用程序堆栈测试,而不是在组件或模块级别。

开发人员和质量保证团队使用构建服务器来启动功能、回归和单元测试; 安全团队还应该利用这些构建服务器来集成安全测试(。例如: SAST,DAST,成分分析,安全单元测试) ,因此它适用于相同的构建过程,并使用所有相同的管理和通信工具。对于安全团队来说,了解开发团队使用哪些工具、谁控制这些资源以及安排安全测试的集成非常重要。

  • 一切都是代码

应用程序就是软件。这是相当容易理解的,但是在许多环境中——特别是公共云环境中——你的服务器、网络、消息、 IAM 和其他基础设施的每一个都可能被定义为配置脚本、模板或应用程序代码。IT 团队现在使用由几百行脚本组成的模板定义整个数据中心。安全从业人员的想法是双重的: 安全策略也可以在脚本或代码中定义,并且你可以检查代码的存储库,以确保模板、脚本和代码在运行之前是安全的。这是对于如何进行安全审计需要做出的根本改变。

  • 对开源代码的认识

开放源码软件在应用程序开发中扮演着重要的角色,在开发社区中得到了广泛的接受,几乎不可能找到一个不利用它的新的应用程序开发项目。这意味着很大一部分代码可能没有按照你认为的方式进行测试,或者开发人员可能故意使用老的、易受攻击的版本。

为什么?因为旧版本与他们的代码可以很好的一起工作。如果他们更改某个库,可能会破坏应用程序并需要更多的编码工作。我们鼓励开发人员让代码正常工作,我们也见证了他们为了稳定而努力避免引入新的(例如: 补丁)开源版本。

因此,我们希望你能够明白两点: 你需要在开源代码投入生产之前对其进行测试,并且你需要确保开发人员不会偷偷地将受信任的开源库版本替换为较老的、可能易受攻击的版本。

  • 工具选择与开发过程 

大多数安全团队在将安全性引入应用程序开发时采取的第一步是运行静态分析扫描。这种做法好的一面是大多数安全从业人员都知道什么是 SAST 以及它是做什么的。糟糕的是,大多数时候安全性始于老式的 SAST 工具,这些工具很慢,产生的输出只能被安全人员理解,并且会产生误报警报,而且他们没有与构建过程的其余部分完全集成所需的关键 API。

总而言之,他们的努力是对开发人员的敌意,大多数开发团队的反应是忽略扫描或从构建过程中移除工具。这里有两个关键方面: 你希望选择操作上适合开发模型的工具(更快、更简单、更好) ,并使用实际上能真正有效的工具。让开发人员自己决定,他们总是选择最容易集成的工具,而不是最有效的安全扫描工具。但重要的是,安全团队是安全工具选择过程的一部分,以确保安全扫描提供足够的分析。

  • 安全摩擦和文化动态

大多数应用程序安全团队正在追赶潮流。开发模式(通常)已经变为敏捷开发模式,如果你的一些开发组织支持 DevOps,那么 IT 和 QA 也可能是敏捷模式的。这意味着安全人员是异常的非敏捷; 你所做的或要求的任何事情都会增加时间和复杂性,这与软件工程的目标正好相反。这个主题是如此重要,以至于我已经准备在本文的下一节重点阐述“伸缩安全性” ,讨论如何解决安全性和开发之间的文化摩擦。

  • SDLC 和 S-SDLC

许多应用程序安全团队通过观察软件开发生命周期(SDLC)来处理应用程序安全性,目的是在生命周期的每个阶段应用某种形式的安全性分析。安全 SDLC (S-SDLC)通常包括设计期间的威胁建模、开发期间的成分分析、构建阶段的静态分析以及任意数量的预生产测试。这是一个设置独立于的过程的应用程序安全性程序的好方法。

正如许多大型组织开始理解的那样,你的每个开发团队都使用一个略有不同的过程,而且你的公司完全有可能使用现有的每一个已知的开发过程。这是一个非常头疼的问题,但是 S-SDLC 成为了你的标准: 使用 S-SDLC 作为策略模板,然后将安全控制映射到不同过程中的适当位置。

2.1.5 扩展安全性

正如我们在前文中提到的,大多数开发团队在数量上远远超过了安全团队。例如,本周我与三家中型公司进行了交谈; 开发人员从800人到2000人不等,而安全团队的规模从12人到25人不等。

在安全人员中,他们通常有两个或三个人具有应用程序安全背景。虽然他们可能像独角兽一样罕见,但这并不意味着他们有神奇的力量覆盖所有的开发操作,所以他们需要学习如何在整个企业中扩展他们的经验。此外,他们需要以一种与开发理念相融合的方式进行智慧操作,让软件开发团队执行他们设计的安全控制。

以下是几种比较有效的方法。

  • 实现自动化安全分析

我们已经在某种程度上讨论过了自动化,所以我在这里就长话短说。自动化是帮助安全分析更快、更频繁地执行,而且不需要安全团队的直接操作。执行自动化分析(开箱即用或自定义检查)的安全工具对于跨多个开发团队的扩展至关重要。

没错,这意味着对于你公司中的任何一个构建管道,你都必须将工具集成到这个管道中,所以这需要时间。这意味着不仅扫描是自动化的,而且结果的分发是与其他工具和过程集成的。这就是团队的扩展,也是我们列表中接下来两个项目的工具。

  • 让工程构建失败

开发团队和安全团队之间通常有摩擦。安全团队通常为开发经理提供带有数千个缺陷的安全扫描结果。开发经理将其解释为“伙计,你的代码糟透了,你在开发过程中犯了什么错误,现在就修复漏洞! ” 减少两个团队之间摩擦的方法之一是从静态或动态扫描中获取输出,讨论问题的范围,高危缺陷的含义,并就中期修复的合理性达成一致。一旦每个人都同意什么是高危缺陷,以及在什么时间段内修复漏洞是合理的,你就可以指示安全工具在发现关键错误时使工程构建失败。虽然这个过程需要一些时间来实现,也需要承受一些痛苦来完成,但这种做法改变了安全性和开发之间关系的性质。

让工程构建失败不再是安全说“代码是有缺陷的”,而是让这种做法成为一个公正的工具,报告开发中的缺陷。安全不再是阻碍进步的坏家伙,而是开发现在必须满足的一个新的质量标准以及一个关注代码质量的标准,因为这涉及到安全缺陷。这样的做法还改变了两个团队之间的关系的本质,因为开发人员经常需要帮助来理解缺陷的本质,寻找解决某类缺陷的方法而不是单个缺陷的解决方法,开发人员需要安全团队的帮助。如果构建失败,那么两个团队之间的关系将发生翻天覆地的变化。要实现这一点需要一些时间,并且任何产生误报的安全工具都会放大改变的难度,但是这一步对于 DevOps 团队来说是至关重要的。

  • 度量标准

度量对于理解当前应用程序安全问题的范围至关重要,而安全工具是你收集大多数度量标准的方式。即使你没有让工程构建失败,即使结果没有与任何外部安全共享,集成安全测试到构建服务器和代码存储库是获得可见性和度量的关键。这些指标将帮助你决定将预算花在哪里,是否需要额外的工具、开发人员教育或运行时保护。这些度量标准将是你实现工具、教育和运行时保护的有效性的指南。没有度量标准,你就只是在猜测。

  • 安全冠军

我发现衡量安全性最有效的方法之一是委托自愿的开发人员——那些对安全性有积极兴趣的开发人员——让这个人成为他们开发团队的“安全冠军”。大多数开发人员其实对安全很感兴趣,他们知道安全教育使他们对公司更有价值,这通常意味着加薪。出于安全考虑,这意味着你在安全团队中有了一名联络员,你可以向他们提问,如果他们有问题,他们也会主动来找你。

通常情况下,安全团队通过教育来培养这些关系,拥有一个“卓越中心”,在这个虚拟组织中开发人员和安全专家可以提出一些问题(例如:Slack 频道),将开发人员派去参加安全会议,或者仅仅是像赞助午餐这样的讨论安全主题的活动。不管你怎么做,这都是一个很好的方法来扩展安全性而不需要扩展安全人数,我们建议你留出一些预算和资源,因为它带来的好处远远大于它的成本。

  • 教育培训

如果你想让开发人员了解安全和应用程序面临的威胁,那么你就需要对他们进行教育培训。对工程团队的领导和工程团队的副总裁来说,因为人员的费用问题,所以他们通常受到严格的教育预算限制。

为了填补这一空白,安全团队承担培训特定开发人员的费用,教授这些开发人员缺乏的安全技能,这种情况并不少见。有时是购买与安全有关的 CBT 来实现,有时是购买安全工具供应商提供的专业服务,有时是 SANS 或其他机构提供的特定类别。了解如何修复应用程序的安全问题、安全参考体系结构、如何执行威胁建模以及如何使用安全工具都是很常见的培训主题。

这个系列文章比大多数其他文章都要长一点。在过去的几年里,我们进行了大量的研究。尽管我们试图简明扼要的说出重点,但是为了回答第一部分的问题,我们需要涵盖大量的材料。

接下来,我将讨论如何组合一个安全的 SDLC,以及如何在开发过程中集成安全测试。

三、安全测试集成

在本章中,我们将向你展示如何在你的 DevOps 自动化框架中集成安全性。我们将要解决的问题是“我们希望将安全测试集成到开发管道中,并将从静态分析开始。我们该怎么做? ”、“我们理解“左移” ,但这些工具有效吗? ”以及“ 你建议我们从哪些工具开始,以及如何集成这些工具? 。

由于 DevOps 鼓励在开发和部署的所有阶段进行测试,我们将讨论构建的管道会是什么样,以及适合不同阶段的工具。安全测试通常与质量保证团队可能已经部署的功能测试和回归测试并列。除了这些典型的在构建之后的测试点之外, 你还可以在构建之前在开发人员的桌面上进行测试,在构建之前和之后的代码库中进行测试,以及在预部署阶段进行测试。

3.1 构建过程

在我们接到的几个电话中,有几个高级安全主管不知道构建过程的组成。这并不是一种谴责,因为许多安全人员并没有参与软件生产和交付,所以我们想粗略的阐述一下开发人员使用的过程和术语。如果你对此已经很熟悉,那么请跳到“构建安全工具链”。

大多数读到本章的人都会熟悉“夜间构建”,在这种模式中前一天检查的所有代码都是在夜间编译的。当你习惯性的查看日志,看看构建是否失败以及为什么失败的时候就像你也同样熟悉早晨要喝咖啡的习惯。大多数开发团队已经这样做了十年或更长时间。自动化构建是公司通向支持代码开发的流程的完全自动化道路上许多步骤中的第一步。在过去的几年里,我们已经把我们的“脚踩在地板上”,利用越来越多的自动化来加快软件交付的步伐。

通往 DevOps 的路径通常分为两个阶段: 首先是持续集成,它管理代码的构建和测试;然后是持续部署,它将整个应用程序堆栈组装成一个可执行的环境。与此同时,这个过程的所有阶段都在不断地改进,使其更容易、更快、更可靠。要达到这个目标需要大量的工作,使用的脚本和模板通常需要几个月的时间来构建基础,而将它们变得成熟最终成为可靠的软件交付基础设施则需要几年的时间。

3.2 持续集成

持续集成(CI)的本质是帮助开发人员定期检查小迭代代码的进展。对于大多数团队来说,这需要对一个共享的源代码储存库或服务器进行多次更新,每天还要进行一次或多次构建。在这里的关键是,通过更小、更简单的附加功能,我们就可以更容易、更快地发现代码缺陷。这些本质上是敏捷概念,在驱动代码的过程中实现,而不是在驱动人的过程中实现(比如 Scrums 和 Sprints)。

持续集成的定义在过去的十年里已经发生了变化,但是在 DevOps 的环境下,持续集成意味着代码不仅是使用支持的库构建和集成,而且是通过自动分发进行测试的。此外,DevOps CI 意味着代码变更并不应用于分支,而是直接应用于代码的主体,减少了可能困扰开发团队的复杂性和集成噩梦。

这听起来很简单,但实际上需要大量的基础设施支持工作。构建必须完全脚本化,并且构建过程在代码变更时发生。每次构建成功后,应用程序堆栈都会被打包并传递给测试用户。测试代码在单元测试、功能测试、回归测试和安全测试之前构建,并成为存储库和自动化过程的一部分。

每当新的测试可用时,测试工作就会自动开始,但这也意味着每个新的构建都会应用新的测试。这还意味着,在测试工作可以启动之前,必须自动设置、配置测试系统,并为其输入必要的数据。自动化脚本必须为流程的每个部分提供监控能力,并在事件发生时将成功或失败的信息反馈给开发和运维团队。要创建脚本和工具来实现这一切,需要运维、测试和开发团队紧密合作。

下图显示了容器的自动构建管道,包括安全测试点。再次强调,这种层次的编排不是一蹴而就的,而是一个需要数月建立基础、数年才能成熟的渐进过程。但这正是持续改进的本质所在。

3.3 持续部署

持续部署看起来非常类似于 CI,但是侧重于向终端用户发布软件,而不是构建软件。它包含了一些类似于包装、测试和监控的任务,但有一些额外的不同。在成功完成构建周期之后,结果将提供给持续部署(Continuous Deployment,CD)流程。CD 在自动化和弹性方面又向前迈出了一大步,同时自动化了应用程序堆栈的发布管理、设置和最终配置,然后启动新的应用程序代码。

当我们谈论 CD 的时候,人们有两种方式来接受这个概念。有些团队只是将新版本的应用程序启动到现有的生产环境中。CD 过程让应用层实现了自动化,但不能让服务器、数据或网络层实现自动化。我们发现这在本地应用程序和私有云部署中很常见,一些公有云部署也仍然使用这种模型。

与我们交谈过的安全团队中有很大一部分是真正害怕持续部署的。他们说“你怎么可能允许代码在没有检查和监督的情况下运行! ” ,他们忽略了一点,即代码在所有安全测试通过之前不会启动。一些 CI 管道包含一些测试的手动检查点。根据我们的经验,CD 意味着更可靠和更安全的版本。CD 解决了困扰代码部署的几十个问题,特别是在容易出错的手工变更以及生产和开发之间支持库的修订方面。一旦进行了充分的测试,就没有理由不信任 CD。

并不是所有的公司每天都会在发布产品的过程中发布代码;事实上,只有不到10% 的公司会持续发布产品代码,但是一些著名的公司,如 Netflix,Google 和 Etsy,一旦测试完成,就会自动发布产品代码。但是大多数公司(例如: 那些不在内容或零售垂直领域的公司)没有一个好的业务需要每天发布多次更新,所以他们不需要发布代码。

3.3.1 管理和蓝绿部署

大多数公司都有一个较慢的发布周期,通常每一到三个 sprint 就会有一个“上线”的节奏。我们称这些为“托管发布”,因为执行和计时是手动操作的,不过大多数操作是自动的。此外,这些公司还采用了另一种非常强大的技术:自动化基础设施部署。

在这一阶段, 你可以循环整个基础结构堆栈与应用程序。这些类型的部署依赖于软件运行环境的自动化;这可以很简单的实现,比如支持一个 Kubernetes 集群,或者利用 Openshift 在 Google GCP 中运行 Terraform 模板,或者通过 Cloudformation 模板启动一个完整的 AWS 环境。基础设施和应用程序都是代码,因此两者都是同时启动的。这在公有云部署中正变得越来越普遍。

这种发布方法提供了显著的优势,并为所谓的“蓝-绿”或“红-黑”部署提供了基础。新旧代码并排运行,近似于镜像,各自在自己的一组服务器上运行。旧的代码(即: 蓝色)继续服务于用户请求,而新的代码(即: 绿色)只由选定的用户或测试工具执行。部署是负载均衡级别上的一个简单的重定向,内部用户和活动客户可以慢慢地重定向到绿色服务器,本质上是将这些用户作为新系统的测试人员。

如果新代码通过了所有需要的测试,负载均衡器将所有流量发送到绿色服务器,蓝色服务器就会下线,然后绿色服务器成为了新的蓝色服务器。如果发现错误,负载均衡器会被指向原来的“蓝色”代码,直到有新的修补程序可用。这基本上是生产中的预发布测试,即使发现了缺陷或安全问题,也可以立即进行回滚。

3.4 安全测试阶段

3.4.1 桌面安全测试

集成开发环境(Integrated Development environment,IDE)是大多数开发人员的标准。Visual Studio,Eclipse,IntelliJ 等等,一些是针对特定的语言或环境定制的。这些桌面工具不仅有助于构建代码,而且它们集成了语法检查器、运行时、终端、包和许多其他功能,使构建代码更加容易。

商业安全性供应商为流行工具提供插件,通常提供一种静态分析形式。有时这些工具是交互式的,在编写代码时提供建议,而其他工具在提交代码之前根据需要检查当前修改的文件。甚至有一两个工具实际上并不是作为 IDE 的插件,而是作为一个独立的工具工作,并在代码提交到仓库之前运行。由于代码扫描通常只是开发人员正在处理的模块或容器,因此代码扫描的速度非常快。在这个阶段正确地进行安全扫描可以降低构建服务器在代码提交后发现安全问题并失败的可能性。

我们与使用这些工具的开发团队合作,他们发现这些工具是有效的,并且能够按照承诺交付。与我们交谈的许多开发人员并不喜欢这些安全插件,因为他们觉得这些插件噪音大、让人分心。我们建议尽可能使用这些桌面扫描器,但要认识到使用时的文化障碍,并提醒安全团队可能需要帮助改变文化,并允许随着时间的推移逐渐采用。

3.4.2 代码库扫描

源代码管理、配置管理数据库、容器注册中心和类似于这些类型的工具存储代码,并帮助管理任务,如版本控制,IAM 和审批流程。从安全的角度来看,一些成分分析供应商已经集成了他们的产品,以检查开源版本控制是否正确,以及使用的平台是否包含已知的 CVE。为已知的好版本和其他版本控制特性创建数字指纹的附加设施正变得越来越普遍。

3.5 构建服务器集成

构建服务器构建应用程序。通常由内部开发的多个源代码和开放源代码组成,在构建应用程序时使用许多“工件”是很常见的。幸运的是,像 Jenkins 和 Bamboo 这样的构建服务器在建立之前和之后都有处理这些工件所需的钩子。这通常是测试集成到构建管道中的方式。利用此功能将是安全测试集成的核心。在这个阶段通常集成了成分分析、SAST 和自定义测试。

3.6 预发布

对于“代码完成”或系统测试,将应用程序的所有部分和支持的应用程序堆栈组装在一起,设置一个预生产“准备区域”来模拟生产环境,并促进完整的测试。我们发现了几个最近的趋势,预生产测试就是其中之一。由于公有云资源允许快速弹性和随需应变的资源采购,公司正在开发测试环境,运行 QA 和安全测试,然后再次关闭它们以降低成本。这用于执行以前在生产中执行的DAST测试。在大多数情况下,在大多数情况下,这是利用蓝绿部署模型在与现有的生产环境并行的新环境上运行许多不同类型测试的方法。

四、构建安全工具链

4.1 静态分析

静态应用程序安全测试(SAST)检查所有代码或运行时二进制文件,以支持对常见漏洞的彻底搜索。这些工具在发现缺陷方面非常有效,即使是已经经过人工审计后的代码也是如此。你的选择标准可能归结为扫描的速度,易于集成,结果的可读性和较少的误报。

这些平台中的大多数已经在提供对开发人员有用的分析结果方面做得很不错了,而不仅仅是安全极客。许多产品正在升级,通过 API 或构建脚本提供完整的功能。如果可以选择,可以选择带有 API 的工具集成到 DevOps 流程中,这些工具不需要“代码完成”。

我们已经看到这些测试的使用略有减少,因为它们通常需要几个小时或几天才能运行——在 DevOps 环境中可以防止它们作为认证或部署的通道而内联运行。正如我们在上面的“其他”部分所提到的,大多数团队正在调整以支持带外(或者我们称之为“并行化”)的静态分析测试。如果可能的话,我们强烈建议尽可能内联SAST测试,并且关注新增的代码部分以减少运行时间。

4.2 动态分析

动态应用程序安全测试(Dynamic Application Security Testing,DAST)不是扫描代码或二进制程序(如 SAST) ,而是动态地“爬行”应用程序的接口,测试它对各种输入的反应。这些扫描器不能看到幕后发生了什么,但是它们提供了对代码行为的有价值的洞察力,并且可以清除其他测试在动态代码路径中可能看不到的错误。好消息是它们的误报率很低。

这些测试通常是针对完全构建的应用程序运行的,并且具有破坏性,因此这些工具为了能够在测试环境中更积极地运行,通常需要提供一些设置。就像 SAST 可能需要一些时间来完全扫描代码,,因此在测试中,一个版本通常只针对新代码运行,而整个应用程序扫描是“并行”运行的。

4.3 成分和脆弱性分析

成分分析工具检查开放源码库的版本,以评估开放源码的风险,包括安全漏洞和潜在的许可问题。像 Heartbleed、配置错误的数据库和 Struts 漏洞可能根本不是应用程序测试的一部分,但它们都是关键的应用程序栈漏洞。有些人将漏洞测试等同于 DAST,但是还有其他方法来识别漏洞。

事实上,漏洞扫描有几种类型; 一些看起来像平台配置、补丁级别或应用程序组合等设置来检测已知的漏洞。确保扩大扫描范围,以包括应用程序、应用程序堆栈和支持它的开源平台。

4.4 人工代码审计

一些组织发现完全实现自动化部署有点吓人,因此他们希望在新代码上线之前有人来审计变更——我们理解这一点。但也有很好的安全理由进行审计。在一个像 DevOps 这样以自动化为中心的环境中,使用或认可人工代码审计或安全检查可能看起来是与之相对立的,但是人工代码审计仍然是非常可取的。某些类型的漏洞不是扫描工具可以识别的。

人工代码审计经常捕捉到测试遗漏的明显内容,而开发人员在第一次(唯一一次)通过时可能会遗漏。开发人员编写安全单元测试的能力各不相同。无论是由于开发人员的错误还是审计人员的技能,编写测试用例的人员都可能会遗漏人工审计所捕获的内容。你的工具应该包括人工代码审计——至少对新代码进行定期抽查,或者像 Dockerfile 之类的扫描中经常省略的东西。

4.5 运行时保护

许多公司仍在利用 Web 应用程序防火墙,但 Web 防火墙的使用正在下降。我们看到越来越多地公司在生产环境中使用运行时应用程序自我保护来加强日志记录和保护工作。这些平台提供工具代码,提供运行时保护,并在某些情况下识别应用程序里了哪些代码行是易受攻击的。

DevOps 要求你进行更好的监控,以便收集指标,从而可以根据操作数据进行调整。为了验证新的应用程序部署是否正常运行,通常内置监视和检测。在某些情况下,这些是使用自定义包和 ELK 堆栈实现的,在另一些情况下,则只需在生产环境中打开日志记录和“调试”风格的语句(通常在开发阶段使用)。这在公有云 IaaS 中更为突出,在本地日志不能提供充分可见性的情况下, 你完全负责数据和应用程序安全。

4.6 安全单元测试

单元测试是检查应用程序中较小的子组件或片段(“单元”)。这些测试由程序员在开发新功能时编写,通常由开发人员在代码提交到仓库之前运行,但也可能在构建管道中运行。这些测试应该是长期的,与新代码一起存入代码存储库,并由每个后续的开发人员运行,这些开发人员为代码模块做出了贡献。

对于安全性来说,这些攻击可能很简单(比如针对 web 表单的 SQL 注入) ,也可能是针对被测功能的更复杂的攻击(比如业务逻辑攻击) ,所有这些都是为了确保每一段新代码都能正确反映开发人员的意图。每个单元测试都侧重于特定的代码片段,而不是系统或事务。

单元测试试图在过程的早期捕捉错误,按照Deming的说法,越早识别出缺陷,修复它们的成本就越低。在构建单元测试时, 你将需要支持开发人员和基础设施来体现你的测试,并且还要鼓励团队足够认真地对待测试以构建良好的测试。让多个团队成员编写相同的代码并编写单元测试,有助于识别出单个程序员可能没有考虑到的弱点。

4.7 安全回归测试

回归测试验证最近更改的代码是否仍然按预期的方式运行。在安全方面,这对于确保漏洞得到修复尤为重要。DevOps 回归测试通常与功能测试并行运行ーー在构建了代码堆栈之后。

在某些情况下,这可能需要在一个专用的环境中进行,在这种环境中, 安全测试可能具有破坏性,并在具有真实客户数据的生产服务器上产生一些不可接受的副作用。利用虚拟化和云基础设施可以加快新测试环境的实例化。

测试工作本身通常就是通过自己构建的测试用例利用以前发现的漏洞,无论是作为单元测试还是系统测试都是如此。测试用例的编写人员使用这类测试来确保像密码和证书这样的凭据不包含在文件中,并且基础架构不允许访问端口22或3389。

4.8 混沌工程

混沌工程通常在生产环境中引入随机故障,以了解应用程序环境如何处理不利条件。像 Netflix 这样的公司已经率先在这个领域做出努力,以迫使他们的开发团队理解常见的故障类型,并在他们的代码中构建优雅的故障和恢复。

从安全性的角度来看,如果攻击者可以强制应用程序进入坏的状态,那么他们通常可以强制应用程序执行不打算执行的任务。将坚固性构建到代码中可以提高可靠性和安全性。

4.9 模糊测试

最简单的模糊测试实质上是向应用程序丢弃大量随机的垃圾,看看是否有任何特定(类型)的垃圾会导致错误。许多动态扫描供应商会告诉你他们提供了模糊测试。实际上并非这样。

去参加任何安全会议,比如Black Hat、 DefCon、 RSA 或 B-Sides 后你都会发现,大多数安全研究人员更喜欢通过模糊测试查找易受攻击的代码。这种方式已成为识别可能被攻击者利用的存在缺陷的代码的关键。

在过去的10年里,随着敏捷开发过程,甚至是 DevOps 的出现,开发团队和 QA 团队对模糊测试的使用逐渐减少。这是因为它很慢; 执行一个大型恶意输入测试任务运行需要大量的时间。

这对于 web 应用程序来说不是什么大问题,因为攻击者不可能把所有东西都扔进代码里,但是对于交付给用户的应用程序(包括移动应用程序、桌面应用程序和汽车系统)来说,问题就很大。我们几乎排除了这一部分,因为在使用中很少看到真正的模糊测试,但是对于关键系统,定期和带外模糊测试应该是你的安全测试工作的一部分。

4.10 风险及暴露分析

将来自应用程序扫描中发现的安全问题集成到 bug 跟踪系统中,在技术实现上并不困难。大多数产品都将其作为一个内置的特性提供。困难的部分是弄清楚一旦获得数据后该如何处理。被发现的安全漏洞真的是一个问题吗?如果不是误报,是否可以利用漏洞?相对于其他一切,它的临界性和优先性是什么?如果我们选择解决这个漏洞,我们又该如何从一系列选项(单元测试,补丁,RASP) 中选择一种方式来进行处理?

另一个需要考虑的方面是,这种信息的分布不会使利益相关者超负荷。使用 DevOps, 你需要关闭基础设施、安全测试以及代码等问题的循环。Dev 和 Ops 为大多数漏洞提供了不同的可能有效的解决方案,因此管理安全的人员里面也需要包括运营团队。修补、代码变更、阻断和功能性白名单都是关闭安全漏洞的选项; 所以你需要 Dev 和 Ops 来权衡利弊。

五、安全计划

本章旨在帮助安全人员为应用程序安全程序创建一个大纲或结构。我们将回答一些常见的问题,比如“我们如何开始构建应用程序安全策略? ” “我如何开始合并 DevSecOps? ” 及”我应该遵守什么样的应用程式安全标准? ”我将讨论软件开发生命周期(SDLC) ,介绍在实施计划时需要考虑的安全事项,并参考一些应用程式安全标准,作为应采取哪些安全措施的指引。本章将帮助你制定战略; 下一章将介绍战术工具的选择。

5.1 安全计划和你的 SDLC

安全软件开发生命周期(S-SDLC)本质上描述了安全该如何适应软件开发生命周期的不同阶段。我们将研究 SDLC 中的每个阶段,并讨论哪些安全工具和技术是适当的。

请注意,S-SDLC 通常是作为一个瀑布开发过程描绘的,具有线性进程中的不同阶段,但这实际上只是为了更清晰地描述——实际的 SDLC 可能是敏捷的、极限的,或者像瀑布一样的螺旋式的。有充分的理由将 S-SDLC 基于更现代的 SDLC之上; 但是架构、设计、开发、测试和部署阶段都可以很好地映射到任何开发过程中的开发阶段。它们提供了一个很好的起点,可以将当前的模型和流程适应到 DevOps 框架中。

在我们之前的文章中,我们希望你将 S-SDLC 看作是构建你的安全程序的框架,而不是一个完整的循序渐进的过程。我们认识到这与课堂教学和维基教学有所不同,但是对于每个阶段的安全计划来说更好一些。

5.2 定义和架构

  • 参考安全体系架构

参考安全体系架构适用于不同类型的应用程序和服务,包括 web 应用程序、数据处理应用程序、应用程序的身份和访问管理服务、流或事件处理、消息传递等。架构在公共云环境、 Kubernetes 集群和服务网格环境中甚至更有效——在这些环境中,我们可以通过策略严格控制每个应用程序的操作和通信方式。

对于云服务,我们建议你利用服务提供商关于部署安全的指导方针,尽管他们可能不会称之为“参考安全体系架构” ,但他们确实提供了这些指导方针。了解应用程序平台,并询问软件设计师和架构师他们使用了哪些方法。如果对于传统的应用程序,如果他们给你一个茫然的眼神,不要感到惊讶。但是新的应用程序应该包括流程隔离、分离和数据安全计划,以及完整的 IAM 模型,以促进职责分离和数据访问控制。

  • 操作标准

与你的开发团队一起定义最小的安全测试需求,以及关键的和高优先级的问题。你将需要协商哪些安全缺陷将导致构建失败,并提前定义流程。你可能需要就修复问题的时间框架达成一致,并需要某种类型的虚拟补丁来解决难以修复的应用程序安全问题。你需要预先定义这些事情,并确保你的开发人员和 IT 合作伙伴同意这些事情。

  • 安全需求

就像在代码验收之前必须运行的最小功能测试一样,你将在部署之前运行一组安全测试。这些可能是针对你的团队所写的具体威胁而商定的一系列单元测试。或者你可能要求所有 OWASP 十大漏洞在代码或支持产品中得到缓解,将每个威胁映射到所有 web 应用程序的特定安全控制。

不管你选择什么,你的基准需求应该既考虑到旧的功能,也考虑到新的功能。越来越多的测试需要更多的资源进行验证,并且随着时间的推移可能会减慢测试和部署周期,因此你可以决定哪些测试可以阻止发布,哪些测试可以扫描以便进行后期生产。

  • 监控和度量

如果你将在每个版本中进行小的迭代改进,那么需要修复什么?哪些代码模块对安全有问题?什么是有效的,你如何证明它?度量标准是回答所有这些问题的关键。

你需要考虑需要收集哪些数据,并将其构建到 CI:CD 和生产环境中,以度量脚本和测试的执行情况。这意味着你需要让开发人员和 IT 人员参与收集数据。你将不断改进度量标准的收集和使用,但是从一开始就要对数据的基本收集和传播进行规划。

5.3 设计

  • 安全设计原则

一些应用程序的安全设计和操作原则提供了重大的安全改进。例如用于帮助修补和减少攻击者持久性的临时实例、用于移除攻击表面的不可变服务、用于确保服务器和应用程序正确设置的配置管理、用于配置一致的云环境部署的模板、自动化修复、通过锁定开发人员和 QA 人员而将职责分离出生产资源等等。

同样重要的是,这些方法是 DevOps 的关键,因为它们使软件的交付和管理变得更快更容易。这听起来似乎有很多需要解决的问题,但 IT 和开发人员也投入其中,因为这也使他们的生活变得更加容易。

  • 确保部署管道的安全

随着开发和生产环境更加固定,开发和测试服务器成为更具吸引力的目标。传统上,这些运行环境的安全性很低或根本没有安全性可谈。但是,对安全源代码管理、构建服务器和部署管道的需求正在增长。由于 CI/CD 管道提供了进入生产的自动化路径,你至少需要对这些系统进行更严格的访问控制——特别是构建服务器和代码库。

而且,如果脚本在后台连续运行,并且人工监视很少,那么你将需要额外的监视来捕捉错误和不当使用。许多工具提供了良好的安全性,具有数字指纹、2FA、日志、以角色为基础的访问控制和其他安全特性。当部署在云环境中时,管理台允许控制整个环境,必须非常小心地进行访问控制和职责分离。

  • 威胁建模

威胁建模仍然是最有成效的安全实践之一。虽然 DevOps 没有改变这一点,但它确实为安全团队成员提供了机会,可以指导开发团队成员处理常见的威胁类型,并帮助计划单元测试来应对攻击。

这个时候你需要决定是否在公司内部培养这个人才,还是聘请一个顾问,因为没有哪个产品可以为你做到这一点。威胁建模通常在设计阶段执行,但也可以在开发较小的代码单元时执行,有时也可以通过自建单元测试执行。

5.4 开发

  • 基础架构和自动化优先

自动化和持续改进是关键的 DevOps 原则,对于安全也同样重要。正如前面的文章所讨论的,自动化是必不可少的,因此你需要选择和部署安全工具。我们强调这一点是因为计划很重要,有助于开发人员在交付新代码之前计划出他们需要部署的工具和测试工作。

请记住,许多安全工具需要集成一些开发技能,因此要么计划让你的员工提供帮助,要么参与专业服务。坏消息是,在准备过程中需要预先支付费用和完成工作; 好消息是,未来的每一个构建都将从这些努力中受益。

  • 自动化优先

请记住,开发并不是编写代码和构建脚本的唯一团队——现在操作也是如此。这就是 DevOps 如何将修复和加固带到一个新的水平。运维的 DevOps 角色是提供构建脚本,用于构建开发、测试和生产服务器的基础设施。

好消息是,你现在正在测试的是生产环境的精确副本。模板和配置管理解决了传统 IT 多年来一直努力解决的一个问题: 临时性的无文档的工作“调整”环境使得环境能够正常工作。

同样,要使环境完全自动化需要做大量的工作——在服务器、网络配置、应用程序等等上面——但是它使未来的工作更快、更一致。我们采访的大多数团队每周都会构建新的机器镜像,并更新他们的脚本以应用补丁、更新配置和构建脚本以适应不同的环境。这项工作确保了一致性和安全的基线。

  • 安全代码存储库

你希望为开发人员提供一种简便的方法来获得安全的和(内部)批准的开放源码库。我们的许多客户都保留了经过批准的库的本地副本,使得访问这些资源变得很容易。然后,在将代码部署到生产环境之前,他们使用成分分析工具和脚本的组合,以确保开发人员使用的是经过批准的版本。这有助于减少易受攻击的开放源码的使用。

  • Scrum 中的安全性

如前一章节所述,DevOps 是与流程无关的。你可以根据自己的喜好使用螺旋式,敏捷,或手术团队的方法。但是敏捷 Scrum和看板技术非常适合 DevOps。他们专注于较小的、重点突出的、快速可证明的任务上,这很好地实现了协调一致。我们建议在这个时候设置你的“安全冠军”程序,在每个团队中至少培训一个人学习安全基础知识,并确定哪个团队成员对安全主题感兴趣。通过这种方式,安全任务可以很容易地分配给那些有兴趣并且有一定的技能处理这些任务的团队成员。

  • 测试驱动开发

持续集成的一个核心原则是永远不要将有错误或未经测试的代码提交到代码库中。错误和未经测试的定义取决于你。与编写巨大的瀑布式规范文档以提高代码质量或安全性不同,你正在用函数脚本和程序编写策略文档。单元测试和功能测试不仅定义而且增强安全需求。

许多开发团队使用所谓的“测试驱动开发” ,其中的测试确保所需的功能——并避免不需要的结果——与代码一起构建。这些测试用例被存入代码库,并成为应用程序测试套件的永久部分。安全团队没有充分利用这种类型的测试,但是这是检测特定于代码的安全问题的一个极好方法,而商业工具却没有这样做。

5.5 测试

  • 为失败而设计

DevOps 颠覆了 IT 和软件开发中许多长期坚持的原则。例如,耐久性过去意味着“正常运行时间” ,但现在是更换的速度。带有详细产品规格的大型文档已经被便利贴所取代。对于安全性来说,曾经专注于让代码通过功能需求的团队现在正在寻找赶在其他人之前破坏应用程序的方法。这种“混沌工程”的新方法有意破坏了应用程序的部署,迫使工程师在可靠性和安全性方面进行构建。

詹姆斯 · 维克特的《哥特列特》中有一句话: 对你的代码要刻薄——就像它雄辩地表达了你的思想一样。我们的目标不仅仅是在自动交付过程中测试功能,而且是要真正测试代码的坚固性,并大幅度的提高可接受发行版的最低安全性。

我们通过在应用程序上线之前有意地对其进行各种功能测试、压力测试和安全测试,从而加强了应用程序的性能——减少了安全专家亲自测试代码所需的时间。如果你能够找到某种方法来破坏你的应用程序,那么攻击者也有可能破坏你的应用程序,因此,你需要在应用程序启动之前构建测试以及补救措施。你需要计划这些测试工作,以及构建它们所需的资源。

  • 并行化安全测试

所有敏捷开发方法都有一个共同的问题,那就是如何处理比开发周期更长的测试。例如,我们知道对关键代码片段进行模糊测试所需的时间比敏捷 Sprint 的平均时间要长。对大量代码进行 SAST 扫描通常要比构建过程长一个数量级。DevOps 也是如此—— 使用 CI 和 CD 代码可能在创建后的几个小时内交付给用户,而且可能无法执行完整的白盒测试扫描或动态代码扫描。

为了解决这个问题,DevOps 团队同时运行多个安全测试以避免延迟。他们将大型应用程序分解成服务,以加快扫描速度。针对已知关键问题的验证由单元测试来处理,以便进行快速抽查,并将失败的代码返回给开发团队。代码扫描器通常与单元测试或其他功能测试并行运行。

我们的观点是,作为一名安全专家,你应该寻找加快安全测试的方法。组织效率与速度的测试以及完整性与完成时间的测试,对于我们交谈过的每个开发团队来说,都是一种持续的平衡过程。将扫描集中在代码的特定区域有助于更快地发现问题。一些公司还讨论了维护预填充和完全配置的测试服务器的计划——就像他们维护生产服务器一样——等待下一个测试周期以避免延迟。为了提高效率和快速部署而重写和重新配置测试环境有助于 CI。

5.6 预发布

  • 弹性 FTW

有了公共云和虚拟化资源后,快速提供测试服务器变得更加容易。我们现在可以通过一些 API 调用启动新环境,并在不使用时缩容。利用随需应变的弹性云服务来加速安全测试。

  • 测试数据管理

开发人员和测试人员有一个非常坏的习惯,就是将生产数据复制到开发和测试环境中以改进他们的测试。在过去的几十年里,这一直是许多数据泄露事件的源头。锁定生产环境,这样 QA 和开发人员就不能泄露受管制的数据,这很好,但也确保他们不会绕过你的安全控制。数据屏蔽、标记化和各种工具都可以生成高质量的测试数据,从而最大限度的降低它们使用生产数据的动机。

这些工具提供来自生产数据的测试数据,但去除了敏感信息。这种方法已经证明对于许多公司是成功的,而且大多数厂商为 DevOps 管道提供了合适的 API 或自动化功能。

5.7 部署

  • 手动与自动化部署

通过自动化将新代码推入生产环境非常容易。但对代码进行审查,或者在出现错误时进行回滚,要困难得多。与我们交谈过的大多数团队还不能完全适应全自动化部署——这会吓坏许多安全人员。持续的软件交付实际上只有少数公司使用。

大多数公司每隔几周才向客户发布新代码,通常是在一系列冲刺之后。这些公司通过脚本执行许多部署操作,但是在操作和开发资源可用时手动启动脚本以完全监视推送操作。有些组织确实对完全自动化的生产推送非常满意,每天会发布几次。没有单一的正确答案,但无论哪种方式,自动化都能完成大部分工作,从而腾出人员进行测试和监视。

  • 部署和回滚

为了仔细检查在预部署前的测试中工作的代码能够在开发环境中仍然可以工作,我们交谈过的团队仍然会进行“冒烟”测试,但是他们已经将这些测试进化为自动化和更细粒度的控制。

我们看到了三个常用于增强部署的技巧。

第一个也是最强大的部署称为蓝-绿或红-黑部署。新旧代码并排运行,各自在自己的一组服务器上。在负载均衡器级别,如果发现错误,负载均衡器就会指向旧代码。

第二种是金丝雀测试,其中一小部分单独的会话是针对新代码的——优先的对内部员工的测试人员开放,然后开放给外部客户的子集。如果金丝雀死亡(遇到错误) ,新代码将退出,直到发出的代码可以修复为止,此时将重复该过程。

最后,特性标记通过配置文件启用和禁用新的代码元素。如果在新的代码段中发现了事件错误,则可以关闭该特性,直到该特性得到修复。在不同的模型和组织之间,自动化和人工干预的程度有很大的不同,但总的来说,这些部署比传统的 web 服务环境更加自动化。

  • 生产环境安全测试

即使安全控制失败,应用程序通常也能继续运行。例如,一个新的部署脚本可能会错过对 web或应用层防火墙策略的更新,或者应用程序可能在没有任何防火墙保护的情况下启动。

验证——至少是关键安全组件的健全性检查——对于生产环境是必不可少的。我们采访的大多数大公司都雇佣了渗透测试人员,许多公司都有专职的“红队”来检查应用程序运行时的安全缺陷。

  • 自动化运行时的安全防护

许多公司将 Web 应用程序防火墙(WAF)作为其应用程序安全程序的一部分,通常是为了满足 PCI-DSS 需求。与我们交谈过的大多数公司对这些工具都不满意,所以当他们继续利用 WAF 黑名单时,他们采用了运行时应用程序自我保护(RASP)来填补剩余的空白。RASP 是一种应用安全技术,嵌入到应用程序或应用程序运行时环境中,检查应用层的请求,以实时检测攻击和误用。

除了“应用程序上下文中的 WAF” ,RASP 还可以在应用程序框架的许多地方进行监控和执行,既可以针对特定类型的攻击定制保护,也可以允许 web 应用程序请求“完成” ,直到在阻止请求之前发现某个请求确实是恶意的。在过去三年里,我们接到的几乎所有讨论应用程序安全和 DevOps 的电话都讨论了 RASP,而且我们接触的大多数公司都部署了这项技术。

5.8 应用程序安全标准 

目前已经有一些应用程序安全标准可用。开放式 Web 应用程序安全项目(OWASP) TOP 10和 SANS 常见弱点枚举 TOP 25 是最流行的安全漏洞,但也有其他威胁和常见弱点列表,这些列表通常侧重于特定的子主题,如云部署或应用程序安全度量。每个标准都倾向于被一个或多个标准组织所接受,因此你使用的标准通常取决于你所处的行业。或者你可以把它们都用上。

无论你的选择如何,我们的想法都是了解哪些攻击是常见的,并在构建管道中使用一个或多个安全控制和应用程序安全测试来解释这些攻击。本质上,你构建的是一个威胁矩阵,并将它们映射到安全控制。此步骤将帮助你计划采用哪些安全工具并将这些工具放入构建过程,以及在生产中使用哪些安全工具。

六、安全在DevOps中的角色

正如前面提到的,DevOps 并不完全是工具和技术,但它的成功很大程度上取决于人们在这个模型中的工作方式。我们已经对工具和流程进行了详细的介绍,并且从安全从业者与 DevOps 合作的角度探讨了大部分内容。由于本文主要是为了帮助安全人员,所以我们在这里概述他们在 DevOps 环境中的作用。我们希望这个总结能帮助你和其他团队一起工作,减少摩擦。

虽然我们有意将这篇文章命名为企业 DevSecOps,但请记住,你的开发,IT 同行们认为根本没有这回事。对他们来说,安全性成为集成和交付代码的操作过程的一部分。

我们称安全性为一个独立的东西,是因为当它被编入 DevOps 框架时,安全人员实际上更难适应。你需要了解如何改进安全代码的交付,而不会浪费时间,也不会在你可能并不熟悉的开发过程中引入瓶颈。好消息是,安全性非常适合 DevOps 模型,但是你需要在组织使用的自动化和编排中进行调整以获得成功。

6.1 安全专家的责任

  • 学习 DevOps 模型

在本文中,我们甚至还没有触及 DevOps 的理论和实践。在基本概念和实践方面有很多东西需要你学习。要在 DevOps 环境中工作,你需要了解它是什么以及它是如何工作的。你需要了解文化和哲学上的变化,以及它们如何影响过程、工具和优先级。你需要了解公司的方法,以便最好地集成安全工具和指标。一旦你了解了开发团队的机制,你就会对如何在他们的流程上下文中与他们一起工作有了更好的了解。

  • 学习如何变得敏捷

参与 DevOps 团队意味着你需要适应 DevOps,而不是相反。DevOps 的目标是快、更快、最快: 提供快速反馈的小型迭代更改,最终减少在制品(Work In Progress,WIP)。为提高安全性而进行的小型迭代变更符合这个模型。你将优先考虑那些使得安全软件的交付优于新功能交付的事情,这通常是一项巨大的任务,以改变长期存在的“功能优先”的文化。你需要调整需求和建议,使它们适合于流程,通常简化为小步骤,并提供足够的信息,使任务既可以自动化,又可以被监视。你可以建议进行人工代码审计或模糊测试,只要你了解它们在流程中的适用位置,以及哪些可以发布哪些不能发布。 

  • 培训

我们的经验表明,使开发团队加快安全性的最佳方法之一是培训: 内部解释或演示、帮助应用程序安全的第三方专家、威胁建模、在线学习或各种商业课程。历史的负面影响是成本,许多课程要花费数千美元。你需要评估如何最好地利用你的资源——这个问题的答案通常包括为所有员工提供一些在线教学,选择参加课程的人,然后教同龄人。邀请现场专家教学的费用可能很高,但是整个团队都可以参加培训。 

  • 增加自己的支持

如果没有帮助,安全团队根本无法扩展他们的知识。这并不意味着会有数百名新的安全岗位的员工,而是意味着要委托开发人员帮助产品提高安全性。安全团队通常很小,而且开发人员比例为100:1。

此外,安全人员在大多数开发会议上都不出席,因此他们在日常的敏捷活动中缺乏可见性。为了帮助扩展安全团队的覆盖范围,看看是否可以让每个开发团队中的某个人——也就是所谓的“安全冠军”——充当安全倡导者。这不仅有助于扩展安全团队的覆盖范围,还有助于扩展安全意识。 

  • 帮助 DevOps 团队理解威胁

大多数开发人员并不完全理解攻击者是如何攻击系统的,或者当代码或 SQL 注入攻击是可能出现的时候,这又意味着什么。安全威胁的深度和广度超出了他们的经验,大多数公司不教授威胁建模。

OWASP Top 10是一个很好的指南,指出了困扰开发团队的代码缺陷类型,但是你应该将这些威胁映射回现实世界的示例,展示 SQL 注入攻击可能造成的损害,并解释 Heartbleed 类型的漏洞如何能够完全暴露客户凭证。可以把这些现实世界中的用例看作是“震撼和敬畏” ,这对于帮助开发人员“理解它”大有帮助。

  • 对补救措施提出建议

如果你的安全建议只是“加密数据”或“安装 WAF” ,那么这种建议是不够的。通常情况下,开发人员和 IT 人员对于安全性的构成只有一个单一的想法,他们希望设置并忘记一个单一的工具。帮助构建安全性程序的元素,包括代码内增强和支持工具。教导他们如何帮助解决特定的威胁,并提供部署和策略设置方面的帮助。

过去,公司常常制作代码风格指南,教给年轻的开发人员正确编写的代码是什么样的。通常情况下,这些资源都不是在线的。考虑一个关于安全编码实践和其他参考资料的Wiki页面,这些资料很容易被没有安全背景的人发现并且很容易阅读。 

  • 帮助评估安全工具

对于安全之外的人来说,充分理解安全工具的作用或工作方式是不寻常的。因此,你可以通过两种方式提供帮助: 首先,帮助开发人员选择工具。错误的概念到处都是,这不仅仅是因为供应商承诺的能力过高。此外,对于开发人员来说,评估代码扫描器、活动监视器甚至补丁管理系统的有效性是不常见的。

作为顾问,你有责任帮助 DevOps 了解这些工具能够提供什么能力,以及在你的测试框架中适合什么。当然,你可能无法评估 API 的质量,但是你可以判断一个产品在什么时候不能提供有意义的结果。其次,你应该帮助定位开支,因为掌握资金的人并不总是清楚具体的工具如何解决安全性和遵从性要求。你应该为满足业务需求的工具指定功能和报告要求。 

  • 有优先级的提供帮助

在我们的研究过程中,许多安全专家告诉我们,所有的漏洞看起来都像是高优先级的,区分一个对组织有影响的漏洞和一个没有影响的漏洞是非常困难的。漏洞披露分析领域超出了开发人员的技能范围。你需要帮助填补这个空白,因为并非每个漏洞都会带来真正的风险。

而且,安全人员长期以来都喜欢使用恐怖主义威胁等级,含糊地警告“严重风险”和“高威胁等级”。如果不把威胁和可能的漏洞利用联系起来,不把漏洞利用对企业意味着什么说清楚,或者不知道如何解决和降低风险,这些警告都是没有价值的。

例如,你可以修复代码中一个关键的应用程序漏洞,对支持系统打补丁,如果不是关键的功能禁用则该功能,或者用 IDS 或防火墙进行阻止,甚至是用 WAF 或 RASP 技术进行过滤。或者在漏洞利用实际上并不会损害业务的情况下,“什么都不做”反而是正确的答案。而不是下意识的“天哪!现在就修复它! ” 我们在历史上看到过这样的反应—— 通常有几种选择来修复一个漏洞,所以向 DevOps 团队提出折衷方案可以让他们选择最适合的。

  • 编写测试

DevOps 已经将一些操作和版本管理人员置于一个不舒服的位置,他们必须学习编写脚本,编写代码,并将他们的工作公开给大众评审。它在短期内将人们推出他们的舒适区,但这是在中期内建立一个有凝聚力的团队的关键部分。

安全人员向团队贡献测试是完全可以接受的: 验证证书的扫描、检查已知的 SQL 注入攻击、定位漏洞的开源工具等等。如果你对此感到担心,那么请帮助并集成单元测试和回归测试。融合和迎合!要参加一个 DevOps 团队,其中自动化起着关键作用,你可能需要知道如何编写脚本或模板。

好消息是,你们的策略现在已经体现在环境的定义中。不要害怕你不知道源代码控制或脚本的正确格式; 这是开发人员通常热衷于提供帮助的领域。在将你的测试集成到构建和部署服务器之前,你可以在脚本编写方面学一些东西,但是你要做的不仅仅是宣扬安全性——你也可以做出贡献! 

  • 宣传 

你可以帮助开发团队的一个关键领域是了解公司和外部的策略需求。正如 CVE 条目几乎不告诉你如何修复某个安全问题一样,内部安全和隐私策略执行对于开发团队来说常常是个谜。开发者不能在谷歌上搜索这些答案,所以你可以提供自己作为顾问。你至少应该像开发团队中的任何人一样理解遵从性、隐私、软件授权和安全策略,所以他们可能会感激你的帮助。

展开阅读全文
加载中

作者的其它热门文章

打赏
0
4 收藏
分享
打赏
0 评论
4 收藏
0
分享
返回顶部
顶部