作者:
姚圣伟(现就职天津引元科技 天津市区块链技术创新中心)
研发效能(DevOps)工程师认证学员
一、从DevOps到 DevSecOps
DevOps 最开始最要是强调开发和运维的协作与配合,至今,已不仅仅涉及开发和运维团队。为了更好地发挥出 DevOps 作用,就必须将IT全流程,各工种,融入应用的整个生命周期中 。
虽然 DevOps 的工作方式让开发团队能够更快地部署应用程序,但这就像想要在悬崖上走得更快一样,并没有什么安全可言!
在当下,凭借云,DevOps 团队可以获得前无所有的基础结构和规模。但随之而来的,互联网上一些怀有恶意最多的行动者也可以迅速通过云来接近这些团队,团队每次部署应用程序时都会给业务带来安全风险。
在这样的分布式环境中,外围类别的安全性不再可行,所以公司必须在应用程序和基础结构中采用更多微观级别的安全性,并设立多道防线。
如何通过持续集成和交付来确保应用程序是安全的并保持安全?在早期阶段如何找出安全问题并进行修复呢?这要从通常被称为 DevSecOps 的做法开始。
DevSecOps 是“开发、安全和运营”的缩写,它可在软件开发生命周期的各个阶段自动集成安全性 - 从最初的设计到集成、测试、部署,一直到软件交付[1]。
DevSecOps 代表着开发组织实施安全性的自然且必要的发展过程。过去,安全性总是由单独的安全团队在开发周期结束时(几乎是事后)添加到软件中,并由单独的质量保证 (QA) 团队进行测试。
传统的安全开发流程
在传统的安全开发流程中,安全团队地介入,相对靠后,基本上是产品发布前的一道防线,客观上造成了开发和测试是按照敏捷以及DevOps的流程在运行,到最后一步,有回到了瀑布式的方式进行安全测试,造成了发布的“肠阻塞”。
如果每年只发布一两次软件更新,这种方法还能够应付。但是,随着软件开发人员采用了敏捷和 DevOps 实践,软件开发周期就缩短到几周甚至几天,传统的“添加式”安全方法就造成了让人无法接受的瓶颈。
DevSecOps 可将应用和基础架构安全性无缝集成到敏捷和 DevOps 流程和工具中。它可以在安全问题一出现就解决这些问题,处理起来更加得心应手、速度更快,且成本更低,并且不会将这些问题带入生产环境。此外,DevSecOps 使应用和基础架构安全性成为开发、安全和 IT 运营团队的共同责任,而不仅仅是安全团队一方的责任。它支持“更安全、更迅速地交付软件”- 这是 DevSecOps 的座右铭,可在不减慢软件开发周期的情况下自动交付安全的软件。
DevOps和DevSecOps对照
DevSecOps 将安全团队及其能力整合到 DevOps 做法中,使安全性成为团队中所有人的责任。不再事后考虑安全性,而是在过程的每一步骤中都进行安全性评估。
DevSecOps评估程序安全的四个维度
确保应用程序安全是一个持续的过程,其中包括保护基础结构、设计具有分层安全性的体系结构、持续安全验证和监视攻击。
二、认识威胁和威胁造成的影响
在【研发效能(DevOps)技术工程师认证】培训中,庄俊乾老师在介绍常见的安全漏洞一节课程中,有提到SQL注入问题。OWASP 组织 (Open Web Application Security Project) 在其 OWASP Top 10 2017 文档中将注入列为 Web 应用程序安全性的头号威胁。
我们从课程中,可以发现SQL注入的一些特点:
-
SQL 注入是一种可执行恶意 SQL 语句的攻击。这些语句控制 Web 应用程序背后的数据库服务器。
-
攻击者可使用 SQL 注入漏洞来绕过应用程序安全措施。他们可绕过网页或 Web 应用程序的身份验证和授权,并检索整个 SQL 数据库的内容。他们还能使用 SQL 注入来添加、修改和删除数据库中的记录。
-
SQL 注入漏洞可能会影响使用 SQL 数据库(如 MySQL、Oracle、SQL Server等)的任何网站或 Web 应用程序。罪犯可能会用它在未经授权的情况下访问、删除或更改敏感数据:客户信息、个人数据、商业秘密、知识产权等。
SQL注入的危害不容小觑,历史上有很多著名的SQL注入事件,例如:
2008年,美国俄亥俄州大学的数据库被SQL注入攻击,导致超过36万条敏感数据被泄露,包括学生、教职员工和校友的姓名、社会安全号码、出生日期等。
2011年,索尼PlayStation网络遭到SQL注入攻击,导致超过7700万用户的个人信息被盗取,包括姓名、地址、电子邮件、密码等。索尼因此损失了约1.7亿美元,并面临多起诉讼。
2015年,英国电信公司TalkTalk遭到SQL注入攻击,导致超过150000名客户的个人信息被泄露,包括姓名、地址、电话号码、银行账户等。TalkTalk因此损失了约6千万英镑,并失去了10万名客户。
SQL 注入攻击属于最早、最常见和最危险的 Web 应用程序漏洞。
OWASP Top 10 2017和2021榜单对比
而在不久之前公布的OWASP Top 10 2021榜单[2]中,我们也从榜单中看到,访问控制失效(Broken Access Control)从第五位上升到了第一位。94%的应用程序都经过了某种形式的访问控制失效测试。映射到访问控制失效的34个CWE在应用程序中的出现频率比其他任何类别都要多。
访问控制是指对经过身份验证的用户执行超出其权限级别的操作的限制。当此类限制未正确配置时,就会出现访问控制中断。这可能导致对敏感信息未授权访问以及修改或破坏。
访问控制失效会造成以下严重后果:
-
未经授权的资讯泄露、修改或损坏所有资料,例如用户数据、敏感信息、配置文件等。
-
未经授权的执行超出用户权限的业务功能,例如管理页面、API操作、文件上传等。
-
未经授权的提权,例如未登录即成为用户,或以用户身份登录即成为管理员。
访问控制失效的危害不容小觑,历史上有很多著名的访问控制失效事件,例如:
-
2017年,美国信用评级机构Equifax遭到黑客攻击,导致超过1.4亿美国人的个人信息被泄露,包括姓名、社会安全号码、出生日期、地址等。攻击者利用了Equifax网站上一个已知的Apache Struts漏洞,绕过了访问控制,获取了数据库的访问权限。
-
2018年,Facebook遭到黑客攻击,导致超过5000万用户的账户被盗取,包括姓名、性别、地点等。攻击者利用了Facebook网站上一个“查看个人资料”的功能漏洞,绕过了访问控制,获取了用户的访问令牌。
-
2020年,Twitter遭到黑客攻击,导致多位名人和政治人物的账户被篡改,发布了一些推特诈骗信息。攻击者利用了Twitter员工的内部工具,绕过了访问控制,获取了目标账户的管理权限。
访问控制失效的例子有很多,但大致可以分为以下几种类型:
-
基于URL的访问控制失效:攻击者通过修改URL中的参数或路径,访问到不应该被授权的页面或资源。
-
基于ID的访问控制失效:攻击者通过修改请求中的唯一标识符,如用户ID、订单ID等,访问或修改其他用户的数据或记录。
-
基于方法的访问控制失效:攻击者通过使用不同的HTTP方法,如GET、POST、PUT、DELETE等,执行不应该被授权的操作,如增删改查等。
-
基于元数据的访问控制失效:攻击者通过修改请求中的元数据,如Cookie、JWT、隐藏域等,绕过身份验证或提升权限。
-
基于CORS的访问控制失效:攻击者通过利用CORS(跨域资源共享)的错误配置,从不同的域名访问到不应该被授权的API或资源。
下面是一些具体的访问控制失效的例子:
-
假设一个网站有两种角色,分别是普通用户和管理员。普通用户可以查看自己的个人信息,管理员可以查看所有用户的个人信息。正常情况下,应用程序会根据用户的角色,生成不同的URL,例如:
https://example.com/app/getUserInfo (普通用户)
https://example.com/app/admin_getUserInfo (管理员)
如果应用程序没有对URL进行访问控制检查,那么一个普通用户可以通过修改URL为管理员的URL,从而查看所有用户的个人信息。这就是一个基于URL的访问控制失效的例子。
-
假设一个网站有一个订单系统,每个订单都有一个唯一的订单ID。正常情况下,应用程序会根据用户输入的订单ID,生成如下的SQL语句:
SELECT * FROM orders WHERE order_id = '123456';
如果用户输入正确的订单ID,那么这条语句会返回该订单的信息,否则返回空。但是如果应用程序没有对订单ID进行访问控制检查,那么一个用户可以通过修改订单ID为其他用户的订单ID,从而查看或修改其他用户的订单信息。这就是一个基于ID的访问控制失效的例子。
-
假设一个网站有一个文件管理系统,用户可以上传、下载或删除自己的文件。正常情况下,应用程序会根据用户使用的HTTP方法,执行不同的操作,例如:
GET /files/filename.txt (下载文件)
POST /files/filename.txt (上传文件)
DELETE /files/filename.txt (删除文件)
如果应用程序没有对HTTP方法进行访问控制检查,那么一个用户可以通过使用DELETE方法,删除其他用户的文件。这就是一个基于方法的访问控制失效的例子。
-
假设一个网站使用了JWT(JSON Web Token)来验证用户的身份和权限。正常情况下,应用程序会根据用户登录时生成的JWT,判断用户是否有权访问某些资源或功能。但是如果应用程序没有对JWT进行有效性或完整性检查,那么一个用户可以通过修改或伪造JWT,绕过身份验证或提升权限。这就是一个基于元数据的访问控制失效的例子。
-
假设一个网站有一个API,允许用户从不同的域名访问一些公开的资源。为了实现这个功能,应用程序使用了CORS(跨域资源共享)机制,设置了如下的响应头:
Access-Control-Allow-Origin: *
Access-Control-Allow-Credentials: true
这意味着应用程序允许任何域名访问该API,并且允许发送Cookie等凭证。但是如果应用程序没有对API进行访问控制检查,那么一个攻击者可以通过构造一个恶意的网页,从不同的域名访问该API,并且利用用户的Cookie等凭证,执行一些不应该被授权的操作。这就是一个基于CORS的访问控制失效的例子。
我们可以看到安全问题暴露在整个软件开发周期中,我们需要遵循安全软件开发的要求,迈向更安全编码的第一步。
要遵循安全软件开发的最佳做法,就必须将安全性集成到软件开发生命周期的每个阶段(从需求分析到维护),而无论项目方法如何(Waterfall、Agile 或 DevOps)。随着引入关注的数据泄露和运营方面的安全缺陷被利用等情况的发生,越来越多的开发人员理解了解决安全性问题是需要贯穿整个开发过程的。
在开发生命周期中,解决问题的时间越晚,那么解决问题要耗费的成本也就越高。
安全性问题也不例外。如果在软件开发早期阶段漠视安全问题,那么后面的每个阶段可能会继承前面的阶段中存在的漏洞。最终产品将会积累很多安全问题,还可能会发生数据泄露。将安全性融入开发生命周期的每个阶段,会有助于及早发现问题,并且有助于降低开发成本。
我们按照安全开发生命周期 (Security Development Lifecycle,简称SDL) 的各个阶段来介绍,你可以利用它们在生命周期的各个阶段中完成安全软件开发实践[3]。
SDL 各阶段包括:
安全开发生命周期
三、使用SDL创建现代化的 DevSecOps 框架
由于DevSecOps是对现有软件开发实践的扩展或增强,因此最简单的做法是从敏捷的角度考虑DevSecOps框架,以此来进行规划和设计、编写代码、测试、部署和持续运维。
规划和设计
DevSecOps 在软件开发生命周期的早期阶段开始,通常是设计或规划阶段。例如,安全问题会影响 Sprint planning 期间的目标设置。DevSecOps 框架通过以下方式将安全目标引入规划阶段:
-
建立代码标准并进行同行评审。当开发者以不同的方式编写各部分代码时,安全缺陷可能进入产品中。一个团队如果建立并执行一套一以贯之的代码标准,并依据此套标准评估代码库,可以在极大程度上防止漏洞引入。同行评审可以确保代码确实符合标准并且能够发现常见的编程错误。
-
在IDE环境中使用安全插件。IDE是可扩展的平台,通常可以安装各类安全插件以检查代码中潜在的漏洞,就像 IDE 可以标注出缺少的标点符号或语法错误一样。基于 IDE 的安全检查会在开发者向代码库进行提交之前为他们提供静态代码分析。
-
进行威胁模型分析。威胁建模鼓励开发者像黑客一样对待一个应用程序。开发人员应该考虑到程序会被滥用的潜在风险,同时应该在程序目标设置中考虑到防止滥用的方法。常见的威胁模型分析方法包括STRIDE、DREAD和OWASP。多种威胁模型可以结合起来,以加强设计的安全性。我们可以使用微软的威胁建模工具(Microsoft Threat Modeling Tool)来进行分析,这也是本文将要重点介绍的实践工具。
写代码及代码管理
DevSecOps 不仅仅指有安全意识的代码标准和同行评审。同时还意味着将安全置于代码库管理和维护的中心,以避免引入漏洞。确保代码提交和管理的安全的常用技术包括:
-
管理依赖项的安全性。外部库、开源代码及重复使用的模块在软件开发中很常见。然而,外部代码可能并不遵循与企业内部工作流程一致的安全标准和防范措施。开发者应该检查所有依赖项的安全性,验证他们是否是官方发布的真实版本并安全地交付。
-
扫描代码和代码仓库。代码仓库扫描工具可以在构建执行前对提交到仓库的代码进行静态分析,检查是否存在漏洞、硬编码凭证和其他常见的疏漏。漏洞测试和其他静态测试对于代码安全来说至关重要。代码仓库扫描为大型团队增加了安全性,因为团队中的开发者会访问同一个仓库。
-
保护开发流水线的安全。在检测到安全问题后,一个完整的 DevSecOps 框架可能会调整开发工作流程以防止代码直接提交到默认或主干分支,直到问题得到解决。此外,攻击者还可以通过引入恶意代码或窃取凭证来破坏流水线本身。因此,企业应该在其开发流水线中进行安全管控。
测试
测试可以检测应用程序的缺陷和安全问题。构建、测试和发布流水线的自动化和编排应该包括当代码部署测试时运行的安全工具,如,在单元测试期间检查漏洞。DevSecOps 框架的常见测试注意事项如下:
-
集成动态应用安全测试(DAST)。DAST 和渗透测试历来都是开发过程中的最后一步。DevSecOps 应该将DAST、渗透测试和其他类型的动态漏洞测试加入到流水线内构建阶段的测试方案中。完整的DAST和其他动态漏洞测试,如安全验收测试,可能很耗时,但也可以选择更轻量的测试方案,既可以更快地获取结果也能识别静态测试中遗漏的问题。
-
保护基础设施安全。DevSecOps 的安全考量应该不仅仅局限于应用程序本身,还需要考虑到部署环境,无论是本地还是云端的基础设施(虚拟机、容器、K8S集群等)。借助微软、AWS等工具可以在云基础设施上执行安全驱动的策略。基础设施即代码(IaC)是构建标准和良好应用程序环境的一种方式。
部署和运维
即便构建成功,也并不意味着再也不会出现安全问题。DevSecOps 实践通过以下方式进入部署和运维环境:
-
配置管理。托管应用程序的基础设施环境必须是稳定的。任何试图改变既定基础设施配置的行为都可能是恶意的。监控和执行基础设施配置的工具应该是一个组织的DevSecOps框架的核心要素。云供应商也提供这些工具,如Microsoft Defender for Cloud和Microsoft Sentinel。
-
入侵检测和行为分析。分析工具(入侵检测和预防系统)可以建立流量模式和性能的基准线,然后基于此检测工作负载或网络中可疑或恶意的异常情况。这类工具已经发展成熟,可以被 DevSecOps 所采纳。
-
持续的安全测试。DAST、渗透测试和其他类型的安全测试不应该止步于应用生命周期的测试阶段。定期执行测试(如端口扫描、模糊测试),并且只要团队怀疑代码中存在新的风险就应该进行测试。例如,如果一个新发现的漏洞出现在处理器的命令集中,运维或安全支持管理员应该采取行动。当测试确认了存在潜在的漏洞,他们就可以即刻着手开发和部署新的补丁。
-
告警和报告。安全工具和策略需要配合全面的告警和报告。开发者和项目相关方应该收到可执行的情报以支持及时的鉴别和修复问题。
-
事后复盘。即便做了最佳的安全工作,企业仍有可能最终在应用程序或基础设施中遇到安全问题。当安全事件发生时,进行事后总结是十分必要的。团队应该共同解决问题,并利用经验来调整未来的开发和运维工作,以避免重蹈覆辙。
四、微软威胁建模工具及其使用
威胁建模是安全开发生命周期 (SDL) 的核心元素。这是一项工程技术,可用于帮助识别可能影响应用程序的威胁、攻击、漏洞和对策。可使用威胁建模来塑造应用程序的设计、满足公司的安全目标并降低风险。
当潜在安全问题处于无需花费过多成本即可相对容易解决的阶段,软件架构师可以使用威胁建模工具提前识别这些问题。因此,它能大幅减少开发总成本。考虑到非安全方面的专家,该工具通过提供有关创建和分析威胁模型的明确指导,使所有开发人员可以更轻松地进行威胁建模。
任何人都可以使用该工具来实现以下目的:
-
就其系统的安全设计进行交流。
-
使用经过验证的方法分析这些设计是否有潜在安全问题。
-
提出安全问题的缓解措施并管理缓解措施。
该工具的部分功能和创新:
-
自动化: 有关绘制模型的指导和反馈
-
STRIDE per Element: 引导式威胁分析和缓解措施
-
报表: 验证阶段的安全活动与测试
-
唯一方法: 使用户能够更好地直观了解威胁
-
专为开发人员设计,以软件为中心:许多方法是以资产或攻击者为中心。该工具是以软件为中心。解决方案构建在所有软件开发人员和架构师都很熟悉的活动基础之上 - 例如,为软件体系结构绘图
-
注重设计分析:术语“威胁建模”可以指需求,也可以指设计分析技术。有时,它指的是两者的复杂混合形式。Microsoft SDL 的威胁建模方法是一种有重点的设计分析技术。
威胁建模有五个主要步骤:
-
定义安全要求。
-
创建应用程序关系图。
-
识别威胁。
-
缓解威胁。
-
验证威胁是否得到缓解。
威胁建模的五个步骤
威胁建模应是典型安全开发生命周期的一部分,从而让我们可以优化威胁模型并逐渐降低风险。
开始使用微软威胁建模工具[4]
0、下载并安装 Threat Modeling Tool。访问 https://aka.ms/threatmodelingtool
1、启动 Microsoft Threat Modeling Tool
Microsoft Threat Modeling Tool
2、选择“创建模型”选项。
点击“创建模型”选项
添加 Azure App Service Web App
添加 Azure SQL Database
2、在右侧面板中,搜索并添加 Azure App Service Web App 和 Azure SQL Database,将它们链接起来以显示如下图所示的请求和响应流。
形成请求和响应流
3、在工具栏菜单中,选择“视图”->“分析”视图。分析视图将显示按严重性分类的威胁的完整列表。
4、若要生成威胁的完整报表,请在工具栏菜单中选择“报表”->“创建完整报告”,然后选择保存报表的位置。
系统将生成一份完整报表,其中包括威胁的详细信息、适用的 SLDC 阶段、可能的缓解措施和指向详细信息的链接。
威胁建模工具可帮助解答某些问题,例如:
-
攻击者如何更改身份验证数据?
-
如果攻击者可以读取用户配置文件数据,将造成哪种影响?
-
如果拒绝访问用户配置文件数据库,将发生什么情况?
STRIDE 模型
为了更好地阐明此类突出问题,Microsoft 使用了 STRIDE 模型,它可以将不同类型的威胁分类,简化整体安全交流。
我们可以针对不同的威胁进行状态标注、优先级更改、批示备注等操作。
威胁建模工具风险缓解
当我们使用微软威胁建模工具,创建、配置和分析模型,即完成定义安全要求、创建应用程序关系图、识别威胁后。我们需要进行威胁的缓解,我们可以参考风险缓解类别进行后续步骤。
风险缓解类别
威胁建模工具缓解措施根据 Web 应用程序安全框架分类[5],包括:
它可以帮助识别:
-
最常见的错误发生在哪个位置
-
可在哪个位置实施可行性最大的改进
因此,可以使用这些类别来重点完成并优化安全工作,以便在输入验证、身份验证和授权类别中出现最流行的安全问题时,可以从这些位置着手。最终验证威胁是否得到缓解。
引用:
[1]什么是 DevSecOps?| IBM (https://www.ibm.com/cn-zh/topics/devsecops)
[2]OWASP Top 10:2021榜单 (https://owasp.org/Top10/)
[3]Microsoft Azure 上的安全开发最佳做法 | Microsoft Learn (https://learn.microsoft.com/zh-cn/azure/security/develop/secure-dev-overview)
[4] Microsoft Threat Modeling Tool 概述 - Azure | Microsoft Learn
(https://learn.microsoft.com/zh-cn/azure/security/develop/threat-modeling-tool)
[5]风险缓解 - Microsoft 威胁建模工具 - Azure | Microsoft Learn
(https://learn.microsoft.com/zh-cn/azure/security/develop/threat-modeling-tool-mitigations)