DevSecOps原则

跳哥跳哥 in TIPS 2022-12-12 12:00:01

假如你的安全服务没有自动化,那就不能称之为DevSecOps。通过版本控制、代码审计、重构、动态和静态分析、自动测试等方式,利用它们确保大规模场景下配置、环境和系统行为的一致性来验证和部署IaC设施,确保标准化、审计和安全,减少攻击者发现和利用运维漏洞的机会。

安全左移(Shift Security Left)

这是一个 DevSecOps 时代非常关键的思路转变,其实也很容易理解。持续的发布不停地进行,靠以往把所有的检查在发布之前进行根本跟不上这个速度。所以需要更多的关注研发流程的“左”边,在更早的环节中(设计、编码、自动测试)也要进行安全介入和管控。但安全工作必须从工程师的角度出发,制定更加轻量级可迭代的措施,并以有效、可重复和易于使用的方式实现自动化。这个想法虽好,但并不是那么容易落地,主要的原因是安全人员数量并不足够,所以需要让开发和运维人员承担更多的安全责任,这里需要安全人员对他们进行更多的安全培训(意识和能力),还有就是提供有效的工具来帮助构建更安全的系统。

这一思想诞生了众多的尝试。对需求和架构设计中的快速安全评估机制以及简易威胁建模方法论和工具集等,例如 PayPal 曾在 2016 年的 RSA 大会上分享他们每个团队都必须进行初步的风险评估,并在每一个新应用或微服务开始工作时填写一份自动化的风险调查问卷。又如沉寂多年的源代码安全扫描手段和工具重新被重视(如 GitHub 推出的 CodeQL 等产品),在 IDE 中做更好的集成提供更好的体验等。为了更快地开发代码,敏捷或 DevOps 团队大量使用开源组件、库或框架等代码,据全球最大的开源组件中央仓库服务提供商 Sonatype 的研究报告指出,应用的源码中大约 80%的代码是开源的组件、库或框架代码,由此也引发了开源组件安全以及供应链攻击等视角,也诞生了一些安全工具和解决方案。还有一些人重新思考如何更高效并且将安全融入到单元测试、集成测试等测试环节。总之,围绕这一原则,已经并将继续产生一些探索和安全的解决方案。

默认安全(Secure by Default)

这一思维至关重要。拿编码环节来说,持续的快速构建也意味着需要快速的产生代码,而如何快速的产生安全的代码变的越发重要。在开发人员能力短期无法质变(或不停的有人力交接或新人加入等)时,通过提供默认安全的开发框架或者默认安全的组件可能很好的防止犯低级错误,比如搞 Web 开发的同学肯定知道,一些新的开发框架中都内置了一些安全机制或者安全操作库,比如得益于框架内置的 anti-csrftoken 安全机制,你在一个基于 CodeIgniter 框架并且打开了该项配置的应用中可能很难找到 CSRF 漏洞。再比如当你使用 Go 或 Rust 语言构建系统时,基本上也杜绝掉了 C/C++中常见的缓冲区漏洞及攻击,这是语言特性中默认安全原则的体现。当然,默认安全的原则并不仅仅限于代码,Web 接入层上默认覆盖的 WAF、默认安全配置的云/容器/数据库/缓存等基础系统和服务、统一的登录鉴权认证服务、KMS(密钥管理系统)、保护关键数据的票据系统、零信任(Zero Trust)架构等等,都是默认安全的很好实践。这也要求安全团队要参与到整个系统架构、基础设施等的建设中。反过来也会要求更多的组织架构保障以及安全与研发团队之间的沟通协作能力。

实际的实践中,跟“零信任”等安全思维很相似,表面上看起来好像很简单,其实根本没理解背后所需要做的工作的复杂性。真正想要尽可能的分析系统并且使之各个环节做到默认安全是一件长期和不那么容易的事情。虽然回报巨大,但它要求从根本上改变安全部门与研发部门协同工作的方式。需要两者更紧密的合作起来,一方面增强应用安全和软件设计相关的知识,提升安全编码能力;另一方面要以易用和安全的方式将安全防护措施融入到开发框架、模板、系统架构中,并且还要有持续有效的检查和监控机制。此外,它也需要研发人员及其管理人员做出承诺,要把上述这些默认安全的框架和系统用起来。如果安全不是所有人的一致目标,便很难实施默认安全。

运行时安全(Runtime Security)

这个并不是什么新话题。但是在越来越快的发布之下,倒逼着安全的考量除了上述提到的左移和默认安全以外,更加需要特别关注和加强上线后运行时的异常监控和攻击阻断能力提升。需要有更加及时快速自动化的风险监控、发现、阻断、恢复等的手段和机制。类似于致力于提升系统整体可用性的各种 Monkey(混沌工程),安全机制也需要有类似的机制和能力,重点在识别内外部的安全风险上。再比如与应用运行时环境嵌入更紧密的运行时应用自我保护(RASP,Runtime Application Self-Protection)技术,以前如果还犹犹豫豫,那以后可能会更多纳入大家的视野中。虽然也有一些问题如部署比较麻烦、兼容性问题、性能问题等,但是借助于云、容器等成熟的大规模基础设施和技术之上通过优化完全有可能提供更优雅更易于接受和使用的方案,能够带来更快更精准更细致入微的安全检查及防护能力。此外,对于很多安全风险来说,情报来源管理和自动化分级分析是第一步,然后如何更快的检测?又如何快速地对问题进行响应,特别是为了提升安全响应效能,不能仅仅从单点来考虑,要从全网及整个系统架构层面来考虑,将分散的检测和响应机制整合起来,这也导致了 Gartner 在 2015 年提出了安全编排自动化和响应(SOAR,SecurityOrchestration, Automation and Response)的概念,更好的完成运行时的风险响应问题。

安全服务自动化/自助化(Security as Code/Pipeline)

在 DevSecOps 中,安全并不是特殊或者拥有某种高权限的存在,跟其他所有研发环节和工具一样,不能因为安全而中断 DevOps 的流程。如果你的安全服务没有实现自动化,那么就无法称之为 DevSecOps。整个研发流程都在围绕流水线运转,你不可能突然在其中把开发人员支走,很莫名其妙并且无法被接受。应该向他们提供可使用且易于理解的安全工具,让这些工具自己进行配置和运行,保证这些工具能以合适的方式融入到流水线中,融入到各个流程中,成为 DevSecOps 工具链中的一环,使用角度跟其他工具没有大的区别。总而言之,需确保安全测试和检查服务能够自动化和自助化并且提供快速且清晰的反馈。业界有一些研究和尝试比如漏洞代码自动修复(MIT 的 CodePhage,GitHub 发布的针对开源漏洞组件自动修复的 Dependabot)等技术,虽然目前看有些成熟度可能还不高,这些方向虽然困难但绝对是正确的,是一种贯彻 DevSecOps 思想的尝试。但是这里也要小心陷入另一个误区,需要清晰的认识到,安全领域是没有“银弹”的。如同所有风险类管控一样,信息安全的管控本身一定是层层防御的机制,对于很多营销目的的所谓新技术一定要全面了解多方对比才能做出判断,不太可能指望搞一个方案就一劳永逸的解决所有安全问题,就要达到 100%安全,这是不切实际的空想!就如同软件研发领域“没有银弹”,系统可用性没有 100%(一般我们说要做到 4 个或 5 个 9),安全也没有 100%。

利用基础设施即代码(IaC)

基础设施即代码(Infrastructure as Code)思想和工具是以前成功构建实施 DevOps 的关键,安全管控也要积极的利用这些能力。利用他们确保大规模场景下配置、环境和系统行为等的一致性,通过版本控制、代码审计、重构、动静态分析、自动测试等手段持续交付流水线来验证和部署 IaC 设施,确保标准化、可审核并且使之更安全,减少攻击者发现和利用运维漏洞的机会。各种安全系统和安全机制也积极使用这些设施,另外在出现安全漏洞或应急事件时,直接使用 IaC 的一些机制快速安全可靠的修复漏洞或部署缓解措施。

另一方面,也特别要保护这些基础设施,保护持续集成和持续交付管道等研发流程中的关键系统,真的无法想象流水线系统被恶意控制之后会导致什么。最近几天爆出的有关 SaltStack 自动化运维工具的漏洞造成了不小的影响。所有的操作集中起来对于安全保护的要求会更高,因为对攻击者而言至少目标是更加明确了。

利用持续集成和交付

对于安全来讲,从某些角度来说,快速的持续交付也会带来某些“好处”,要充分利用这些好处。举个例子,大家都知道源代码安全扫描机制有个很大的局限性问题,就是误报率高,这是机制使然。已知的最好的工具可能误报都要在 50%以上,并且这个值很不稳定,对于特定的代码误报率会更高。以前写 1 周的代码,提交增量代码触发扫描可能要发现 100 个疑似漏洞需要花费额外时间来排查,最终有效的是 50 个(假设)。现在如果每天要发布好几次,快速的发布也意味着每次所需扫描的增量代码量大大降低,即使还按照 50%的误报率,可能一共就只有 10 个疑似需要确认,事情就变成了可以接受的情况。这样这些以前搁置的安全工具就有可能有效的使用起来。从本质上说,更快速的变更意味着每次变更的范围更小且独立性更强,轻量级的变更更容易被理解和检查,所需的测试也会更快,错误也会更容易发现,发现问题时修改起来也更简单。当然,如果你的代码更加标准化(如代码风格、代码规范、框架及架构等),这一点会越有利。有一些研究结论也表明,研发安全领域,轻量而频繁的变更可能让系统变得更安全。从腾讯以往的漏洞数据来看,一些老旧的站点确实存在着大量的漏洞不断的被发现。如此看来,对于安全来说,变更很快,或许也并不总是坏事。

需要组织和文化建设

DevOps 以及 DevSecOps 并不像某些 ERP 软件系统那样,买一套部署,然后用起来就解决了。对于一些想要践行的公司来说,DevSecOps 工具链需要去提取痛点(需求)、购买/研发系统并部署、推广使用以及建立度量这样一个正向循环才能持续发展,并由一个个业务、部门逐步试用推广变成整个公司的研发方法论,在这个过程中也需要辅以研发文化的建设。这个过程还需要结合各个公司的一些实际情况来具体问题具体分析,以一步步解决问题提升研发效能的方式来制定适合自己的 DevSecOps 实践方案。比如谷歌会有专门的组织架构及员工角色 SRE(Site Reliability Engineering)联合他们的专业安全团队来共同践行 DevSecOps,而腾讯因为历史上业务和技术发展情况的不同,组织架构上可能需要通过内部的开源协同方式来聚集一些团队共建 DevOps 及 DevSecOps。

除了以上原则外,最后还有一点需要留意。就是要特别关注安全建设的衡量和实际效果的评估和改进,安全不是一蹴而就,要结合内外力量避免虚假的安全感。一些措施如经常性的红蓝军(Red Teaming)对抗渗透测试(Pen Testing)、针对外部安全研究人员的漏洞奖励计划(Bug Bounties)、完善的安全事件复盘等都是一些已知的不错实践。

-- End --

相关推荐