你当前正在访问 Microsoft Azure Global Edition 技术文档网站。 如果需要访问由世纪互联运营的 Microsoft Azure 中国技术文档网站,请访问 https://docs.azure.cn

保护开发生命周期的建议

适用于此 Azure Well-Architected Framework 安全清单建议:

SE:02 使用强化的、大部分是自动化且可审核的软件供应链来维护安全的开发生命周期。 使用威胁建模来整合安全设计,以防止安全失效的实现。

相关指南威胁分析

本指南介绍通过在整个开发周期应用安全最佳做法来 强化代码、开发环境和软件供应链的建议 。 若要了解本指南,应了解 DevSecOps。

安全周期示意图。

DevSecOps 通过以下方式将安全性集成到 DevOps 流程中:

  • 自动执行安全测试和验证。

  • 实现安全管道等工具来扫描代码和基础结构即代码 (IaC) 漏洞。

工作负载的核心是实现业务逻辑的应用程序代码。 代码和开发代码的过程必须 没有安全缺陷 ,以确保保密性、完整性和可用性。

仅仅使用对标识和网络的控制以及其他措施来保护基础结构平面是不够的。 防止代码实现错误或代码块遭到入侵 ,以增强整体安全态势。 还必须强化使用平面(即应用程序代码)。 将安全性集成到开发生命周期的过程本质上是一个强化过程。 与资源强化一样,加强代码开发也与上下文无关。 重点是增强安全性,而不是应用程序的功能要求。 有关强化的信息,请参阅 强化资源的建议

定义

术语 定义
安全开发生命周期 (SDL) Microsoft 提供的一组支持安全保证和合规性要求的做法。
SDLC) (软件开发生命周期 用于开发软件系统的多阶段系统化过程。

关键设计策略

安全措施应在多个点集成到现有软件开发生命周期 (SDLC) ,以确保:

  • 设计选择不会导致安全漏洞。

  • 应用程序代码和配置不会由于可利用的实现和不正确的编码做法而产生漏洞。

  • 通过供应链获取的软件不会引入安全威胁。

  • 应用程序代码、生成和部署过程不会被篡改。

  • 通过事件揭示的漏洞得到缓解。

  • 未使用的资产已正确停用。

  • 合规性要求不会受到损害或减少。

  • 审核日志记录是在开发人员环境中实现的。

以下部分提供 SDLC 常见阶段的安全策略。

要求阶段

要求阶段的目标是 收集和分析应用程序的功能和非功能要求 或应用程序的新功能。 此阶段非常重要,因为它有助于创建根据应用程序目标定制的防护措施。 在整个开发生命周期的每个阶段,保护应用程序的数据和完整性应该是一项核心要求。

例如,假设某个应用程序需要支持允许用户上传和操作数据的关键用户流。 安全设计选项应涵盖用户与应用程序交互的保证,例如对用户标识进行身份验证和授权、仅允许对数据执行允许的操作以及阻止 SQL 注入。 同样,涵盖非功能性要求,如可用性、可伸缩性和可维护性。 安全选择应包括分段边界、防火墙入口和出口以及其他跨领域安全问题。

所有这些决策都应能很好地定义应用程序的安全状况。 在商定的规范中记录安全要求 ,并将其反映在积压工作中。 它应明确说明安全投资,以及如果投资未获得业务利益干系人批准,企业愿意承担的权衡和风险。 例如,可能需要在应用程序前面使用 Web 应用程序防火墙 (WAF) ,例如 Azure Front Door 或 Azure 应用程序网关。 如果业务利益干系人没有准备好接受运行 WAF 的额外成本,他们需要接受应用程序层攻击可能指向应用程序的风险。

安全要求收集是此阶段的关键部分。 如果不进行此努力,设计和实现阶段将基于未说明的选择,这可能导致安全漏洞。 你可能需要稍后更改实现以适应安全性,这可能很昂贵。

设计阶段

在此阶段 ,安全要求将转换为技术要求。 在技术规范中,记录所有设计决策,以防止在实现过程中出现歧义。 下面是一些典型任务:

定义系统体系结构的安全维度

使用安全控件覆盖体系结构。 例如,根据 分段策略在隔离边界上实际使用的控件、应用程序组件所需的标识类型以及要使用的加密方法的类型。 有关一些示例体系结构,请参阅 标识和访问管理 以及 网络 文章的示例部分的插图。

评估平台提供的提供

了解 你与云提供商之间的责任划分非常重要。 例如,避免与 Azure 本机安全控制重叠。 你将获得更好的安全覆盖,并能够根据应用程序的需求重新分配开发资源。

例如,如果你的设计在入口中调用 Web 应用程序防火墙,则可以将责任转移到负载均衡器(如 应用程序网关 或 Azure Front Door) 上。 避免在应用程序中将功能复制为自定义代码。

仅选择受信任的框架、库和供应链软件。 你的设计还应指定安全版本控制。 应用程序依赖项应源自受信任的参与方。 第三方供应商应能够满足你的安全要求 ,并分享其负责任的披露计划。 应及时报告任何安全事件,以便采取必要的措施。 此外,组织可能禁止某些库。 例如,软件可能受到漏洞的侵害,但由于许可限制,软件仍然被禁止。

为了确保软件的所有参与者都遵循本指南, 请维护已批准和/或未经批准的框架、库和供应商的列表。 如果可能,请在开发管道中放置护栏以支持列表。 尽可能 自动使用工具来扫描依赖项 中的漏洞。

确定应用程序代码应实现的安全设计模式。

模式可以支持安全问题,例如分段和隔离、强授权、统一应用程序安全性和新式协议。 某些操作模式(如隔离模式)可以帮助验证和阻止使用可能引入安全漏洞的软件。

有关详细信息,请参阅 支持安全性的云设计模式

安全地存储应用程序机密

安全地实现应用程序机密和应用程序使用的预共享密钥的使用。 凭据和应用程序机密绝不应存储在源代码树中。 使用 Azure 密钥保管库等外部资源来确保,如果源代码可供潜在攻击者使用,则无法获取进一步的访问权限。 一般情况下,请找到避免机密的方法。 尽可能使用托管标识是实现该目标的一种方法。 有关详细信息,请参阅 管理应用程序机密的建议

定义测试计划

为安全要求定义明确的测试用例。 评估是否可以 在管道中自动执行这些测试。 如果你的团队有手动测试的流程,请包括这些测试的安全要求。

注意

在此阶段执行威胁建模。 威胁建模可以确认设计选择是否与安全要求保持一致,并公开应缓解的差距。 如果工作负荷处理高度敏感的数据,请投资可帮助你进行威胁建模的安全专家。

初始威胁建模练习应在定义软件的体系结构和高级设计时在设计阶段进行。 在该阶段执行此操作有助于在将潜在安全问题纳入系统结构之前识别它们。 但是,此练习不是一次性活动。 这是一个持续的过程,应该在整个软件的演变过程中继续。

有关详细信息,请参阅 威胁分析建议

开发和测试阶段

在此阶段,目标是防止代码、生成和部署管道出现 安全缺陷 和篡改。

在安全代码实践方面接受过良好培训

开发团队应 接受安全编码实践方面的正式和专业培训。 例如,Web 和 API 开发人员可能需要特定的培训来防范跨站点脚本攻击,而后端开发人员可以从深入培训中获益,以避免 SQL 注入攻击等数据库级攻击。

应要求开发人员先完成此培训,然后才能获得对生产源代码的访问权限。

还应执行内部对等代码评审,以促进持续学习。

使用安全测试工具

执行威胁建模以评估应用程序体系结构的安全性。

使用 静态应用程序安全测试 (SAST) 来分析代码中的漏洞。 将此方法集成到开发人员环境中,以实时检测漏洞。

在运行时 (DAST) 使用动态应用程序安全测试 。 此工具链可以检查安全域中的错误,并模拟一组攻击来测试应用程序的安全复原能力。 如果可能,请将此工具集成到生成管道中。

遵循行业标准的安全编码做法。 有关详细信息,请参阅本文的社区 资源 部分。

使用 linters 和代码分析器防止凭据推送到源代码存储库。 例如,.NET Compiler Platform (Roslyn) 分析器检查应用程序代码。

在生成过程中, 使用管道加载项捕获源代码中的凭据。 扫描所有依赖项,如第三方库和框架组件,作为持续集成过程的一部分。 调查工具标记的易受攻击的组件。 将此任务与其他可检查代码改动、测试结果和覆盖率的代码扫描任务组合在一起。

结合使用测试。 有关安全测试的一般信息,请参阅 安全测试建议

编写足够多的代码

减少代码占用空间时,还可以减少出现安全缺陷的可能性。 重复使用已在使用且已通过安全验证的代码和库 ,而不是重复代码。

利用 Azure 功能是防止不必要的代码的另一种方法。 一种方法是使用托管服务。 有关详细信息,请参阅使用平台即服务 (PaaS) 选项

默认情况下,使用“全部拒绝”方法编写代码。 仅为需要访问权限的实体创建允许列表。 例如,如果代码需要确定是否应允许特权操作,则应编写它,使 拒绝 结果成为默认情况,并且仅当代码明确允许时才发生 允许 结果。

保护开发人员环境

开发人员工作站需要 通过强大的网络和标识控制来保护,以防止泄露。 确保努力应用安全更新。

生成代理具有高度特权,可以访问生成服务器和代码。 它们必须受到与工作负荷组件相同的严格保护。 这意味着 对生成代理的访问必须经过身份验证和授权,它们应使用防火墙控制进行网络分段,它们应受到漏洞扫描的影响,等等。 应优先使用 Microsoft 托管的生成代理,而不是自承载生成代理。 Microsoft 托管的代理为管道的每次运行提供清洁虚拟机等优势。

自定义生成代理会增加管理的复杂性,并可能成为攻击途径。 必须安全地存储生成计算机凭据,并且需要定期从文件系统中删除任何临时生成项目。 可以通过仅允许来自生成代理的传出流量来实现网络隔离,因为它使用与 Azure DevOps 通信的拉取模型。

源代码存储库也必须受到保护。 在需要知道的基础上授予对代码存储库的访问权限,并尽可能减少漏洞暴露,以避免攻击。 有一个彻底的过程来审查代码 是否存在安全漏洞。 为此,请使用安全组,并实施基于业务理由的审批流程。

保护代码部署

仅仅保护代码是不够的。 如果它在可利用的管道中运行,则所有安全工作都是徒劳无益且不完整的。 还必须保护生成和发布环境, 因为你想要防止恶意参与者在管道中运行恶意代码。

维护集成到应用程序中的每个组件的最新清单

集成到应用程序中的每个新组件都会增加受攻击面。 为了确保在添加新组件或更新新组件时正确负责并发出警报,应提供这些组件的清单。 将其存储在生成环境外部。 定期检查清单与生成过程中的内容匹配。 这样做有助于确保不会意外添加包含后门或其他恶意软件的新组件。

管道任务

  • 从受信任的源(如Azure 市场)拉取管道中的任务。 运行管道供应商编写的任务。 建议执行 GitHub 任务或GitHub Actions。 如果使用 GitHub 工作流,则首选 Microsoft 创作的任务。 此外,验证任务,因为它们在管道的安全上下文中运行。

  • 管道机密。 在管道内运行的部署资产有权访问该管道中的所有机密。 为管道的不同阶段设置适当的分段 ,以避免不必要的曝光。 使用管道中内置的机密存储。 请记住,在某些情况下可以避免使用机密。 了解将工作负载标识 (用于管道身份验证) 和托管标识 (用于服务到服务身份验证) 。

将不同的环境分开

在不同环境中使用的数据必须保持独立。 不应在较低环境中使用生产数据 ,因为这些环境可能没有生产环境具有的严格安全控制。 避免从非生产应用程序连接到生产数据库,并避免将非生产组件连接到生产网络。

渐进式曝光

使用渐进式公开,根据所选条件 向部分用户发布功能 。 如果出现问题,将对这些用户造成的影响降到最低。 此方法是一种常见的风险缓解策略,因为它减少了外围应用面积。 随着该功能的成熟,并且你对安全保证更加有信心,你可以逐渐将其发布给更广泛的用户。

生产阶段

生产阶段提供了 修复安全漏洞的最后一个负责任的机会。 保留生产中发布的黄金映像的记录。

保留版本控制的项目

保留所有已部署资产及其版本的目录。 在事件会审、缓解问题以及使系统恢复工作状态时,此信息非常有用。 还可以将版本控制资产与已发布的常见漏洞和披露进行比较, (CVE) 通知。 应使用自动化来执行这些比较。

紧急修复

自动化管道设计应能够灵活地 支持常规部署和紧急部署。 这种灵活性对于支持快速且负责任的安全修复非常重要。

发布通常与多个审批入口相关联。 请考虑创建紧急流程来加速安全修复。 此过程可能涉及团队之间的通信。 管道应允许快速前滚和回滚部署,以解决在常规部署生命周期之外发生的安全修补程序、关键 bug 和代码更新。

注意

始终优先考虑安全修补程序,而优先于便利性。 安全修补程序不应引入回归或 bug。 如果要通过紧急管道加速修复,请仔细考虑可以绕过哪些自动测试。 根据执行时间评估每个测试的值。 例如,单元测试通常可快速完成。 集成或端到端测试可以长时间运行。

维护阶段

此阶段的目标是 确保安全状况不会随着时间的推移而下降。 SDLC 是一个正在进行的敏捷过程。 前一阶段中介绍的概念适用于此阶段,因为要求会随时间而变化。

修补程序管理。 使用安全修补程序和更新使软件、库和基础结构组件保持最新。

持续改进。 通过考虑代码评审、反馈、经验教训和不断演变的威胁,持续评估和提高软件开发过程的安全性。

解除已过时或不再使用的旧版资产的授权。 这样做会减少应用程序的表面积。

维护还包括事件修复。 如果在生产中发现问题,则需要立即将其重新集成到流程中,这样它们就不会重复发生。

持续改进安全编码做法,以跟上威胁形势。

Azure 便利化

Microsoft 安全开发生命周期 (SDL) 推荐可应用于开发生命周期的安全做法。 有关详细信息,请参阅 Microsoft 安全开发生命周期

Defender for DevOps 和 SAST 工具包含在 GitHub Advanced Security 或 Azure DevOps 中。 这些工具可帮助你跟踪组织的安全分数。

遵循以下资源中所述的 Azure 安全建议:

若要在源代码中查找凭据,请考虑使用 GitHub Advanced SecurityOWASP 源代码分析工具等工具

验证应用程序中任何开放源代码的安全性。 这些免费工具和资源可以帮助你进行评估:

安全清单

请参阅完整的一组建议。