You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

135 lines
14 KiB
Markdown

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

# 24 | SDL怎样才能写出更“安全”的代码
你好,我是何为舟。
安全漏洞的源头是开发,只有当开发人员写出了包含安全漏洞的代码,黑客才有可乘之机。因此,如何保障开发写出更“安全”的代码,是安全防护工作中最关键的一环。
2004年微软提出了SDLSecurity Development Lifecycle安全开发生命周期。因为对安全和隐私的考虑贯穿了整个软件的开发进程SDL能够帮助开发人员写出更“安全”的代码在解决安全合规需求的同时也能减少由安全问题带来的损失。
和安全标准一样SDL本质上是一个宏观指导性质的框架。但是它确实成为了很多公司建设安全开发体系的参照标准。各个公司依据微软的SDL标准结合自身的实际情况衍生出了适合公司自身发展的SDL。今天我们就一起来学习到底什么是SDL以及SDL是如何让开发写出更安全的代码的。
## SDL中的基础概念
我们先来看一个软件开发中的经典概念软件开发生命周期DLCSoftware Development Life Cycle这个概念的英文缩写种类比较多为了和SDL区分我们用DLC代表软件开发生命周期。SDL是以软件开发生命周期为基础发展成的安全框架所以了解DLC能够帮助我们更好地认识SDL。
DLC将软件开发过程分为5个阶段需求分析、设计、开发、测试和部署。DLC对[5个阶段](https://blog.csdn.net/chktsang/article/details/87007831)的具体描述,都是以业务功能为核心进行展开的,并没有涵盖安全的工作。这显然不安全。
而且我们都知道安全问题对公司的威胁是客观存在的。因此很多公司将安全纳入到测试的工作中。但是这种做法会导致两个问题第一安全问题要等到软件开发完成后才能发现。这个时候因为一个安全隐患不是BUG让开发人员重启开发流程推动上会遇到较大的阻力第二只能关注到最终完成的软件往往会导致安全人员因为对业务了解不足漏过一些安全隐患。这些问题的出现让业内亟需一个能够更好地满足安全需求的软件开发流程SDL也就应运而生了。
## 什么是SDL
SDL的出现不是为了颠覆传统的DLC框架而是希望在DLC中加入足够清晰的安全需求以此来为软件开发的过程提供完整的安全防护。SDL的[标准执行流程](https://www.microsoft.com/en-us/securityengineering/sdl/practices)有7个步骤安全培训、需求分析、设计、开发、测试、部署和响应。流程如下图
![](https://static001.geekbang.org/resource/image/e7/88/e7318aeeafb718cd225f5e8fedb26488.png)
接下来,我们就一起来看一下,这些步骤中都包含哪些安全工作。
### 1\. 培训
在SDL中安全培训是第一步。之所以会这么设计就是因为很多公司都对安全人员给予了过高的期望认为他们能够解决一切的安全问题而忽略了对开发、测试、运维等人员的安全意识培训。这就导致安全人员一直处于一个“救火”的状态无法从根本上杜绝安全问题的产生。
因此SDL中明确提出开发、测试、运维和产品经理每年至少进行一次安全培训。培训的内容包括安全概念和框架、威胁评估、Web安全、安全测试以及隐私保护等。
### 2\. 需求分析
SDL要求在需求分析的过程中我们必须把安全防护的需求考虑进来。在需求分析阶段安全人员提出的防护需求主要包括三个方面。
* **安全标准**:为软件制定对应的安全标准。比如,需要对敏感数据进行加密存储、需要进行二次认证等。
* **安全指标**:定义软件在上线时需要满足的安全指标。比如,在上线时,软件必须经过安全测试,且不允许存在任何高危漏洞。
* **风险点评估**:安全人员会对整体需求进行评估,找出需要对安全性重点关注的部分,也就是风险点。比如某个需求会使用到用户的隐私数据,那么风险点就是这些隐私数据。
这三个方面的安全需求,能够为软件开发划定最低的安全保障,也能够时刻提醒软件开发环节的各个人员保持对安全的关注。
### 3\. 设计
对需求进行分析整理之后,我们就需要对软件的功能和架构进行设计了。那我们都需要设计些什么呢?其实就是为后续的开发、测试和部署环节制定响应的方案和计划。针对上面整理出的三个方面的安全需求,我们也需要在设计环节中,给出具体的实现方案。
* 为安全标准确定具体的实施方案。比如,对敏感数据做加密存储,那么,具体的加密算法是什么,密钥怎么生成和存储,都需要在设计阶段确定方案细节。
* 安全指标的响应方案则是在软件开发方案中,尽可能地考虑安全问题,降低可能出现风险的概率。比如,依据最小权限原则,明确软件每个用户和角色能够进行的操作。或者确定审计需求,明确各个阶段需要记录的日志及时发现攻击行为。
* 对于需求阶段定义的风险点进行完整的风险评估。依据识别数据、攻击和漏洞的方式,明确需要采取的安全防护机制,提升这些关键风险点的安全性。
在设计的过程中,我们需要对安全和开发成本进行平衡考量,使得最终的安全设计方案能够被所有项目人员认可。
### 4\. 开发
在开发阶段,安全人员的工作则是尽可能地避免开发人员的代码出现安全问题。那究竟应该怎么做呢?其实,我们可以通过限制工具和方法、定期审查代码来实现。
首先我们可以限制开发人员使用的工具和方法。比如为了避免插件漏洞我们可以只允许开发人员使用通过我们验证的插件和工具为了避免SQL注入漏洞的出现我们可以限制开发人员使用字符串拼接的方式执行SQL等。
其次,我们也需要对开发人员产出的代码进行定期的安全审查,通过人工或者工具分析,发现一些没有得到限制的安全漏洞。比如,没有对用户的输入进行验证等。
### 5\. 测试
在测试阶段,测试人员会对软件的功能进行测试,安全人员需要对软件的安全性进行测试。测试的内容主要包括两个方面。
一方面我们需要评估软件是否符合当初的安全设计方案是否存在不一致的地方。有的时候虽然我们在设计的时候考虑了最小权限原则但是在实际开发的过程中也可能由于开发人员的理解偏差或者BUG导致权限滥用的出现。因此在测试阶段我们需要依据当初的安全设计方案一项一项去确认是否符合要求。
另一方面,我们要进行动态的安全测试。动态测试的方法有两种,执行漏洞扫描和进行模糊测试。漏洞扫描很好理解,我们可以通过向软件发起一些测试性的攻击脚本,来验证是否存在漏洞。模糊测试就是不断向软件发起随机或者异常的请求,然后看软件是否出现报错等情况,以此来检测可能存在的漏洞。
### 6\. 部署
在测试完成之后,软件就可以准备部署上线了。
到这一步可以说安全人员已经把安全漏洞出现的可能性降到最低了。但是我经常说“没有100%的安全,安全人员需要随时为可能发生的安全事件做好防护准备”,所以,在软件上线前,我们需要做好安全预案。
我来举个例子。一旦出现数据泄露事件,运维人员必须第一时间对数据库进行隔离,开发人员需要下线软件相关功能,产品人员需要做好用户的安抚工作,安全人员需要立即对相关日志进行保存,然后分析事件产生的原因。这就是一个安全预案的基本框架,但是每一步的具体操作,还需要我们根据实际情况来细化。
预案准备完成之后我们还需要再一次进行安全确认工作。这个过程主要是来确定软件的整个开发流程是否有严格按照既定的SDL流程进行以及最终的软件是否满足我们开始提出的三个安全需求。
在各项事情都确认完毕之后,我们就需要对整个项目进行归档了。归档之后,包括代码、需求列表、设计方案和应急预案在内的所有的内容都不允许改动。
完成了安全预案、安全确认和归档之后,我们就可以进行软件的最终部署上线了。
### 7\. 响应
软件上线之后,安全人员所需要做的,就是及时响应和处理安全事件。这就需要用到我们在部署阶段制定的安全预案了,为了执行这个安全预案,我们需要成立安全应急响应小组。这个小组的工作就是对安全事件以及外界的漏洞情报进行监控,一旦发现安全事件立即对事件进行评估,决定需要启动的安全预案。通过安全应急响应小组,我们可以保持对线上软件安全的时刻监控,保障软件的安全和稳定。
现在相信你已经能够理解SDL是如何从根源上解决安全问题的了。我来简单总结一下SDL通过安全培训来解决人的问题然后在需求和设计阶段提出安全需求在开发和测试阶段发现安全漏洞最终在部署和响应阶段处理安全问题。
## 如何推动SDL落地
尽管SDL能够从根本上解决安全问题但是SDL的落地却依然存在较大挑战。最主要的原因就在于SDL更像一个规章制度它必须获得开发人员的认可而大部分的开发人员很排斥安全制度。
尽管如此为了提升公司的整体安全性我们要尽力推动它落地。那究竟该怎么做呢我们可以从三方面入手降低推动SDL落地的难度。
**1\. 我们要基于现有的制度拓展SDL。**
如果公司已经比较成功地实施了DLC那SDL的成功落地就已经实现一半了。因为这说明开发人员已经在一定程度上认可或者接受了这种制度化我们只需要在此基础上再加入一部分安全内容就能实现SDL的落地了。这对开发人员的影响不大也就更容易接受。
因此我个人建议不要从零开始强推SDL应该循序渐进先定义好普通软件开发的制度再加入安全元素。
**2\. 我们在落地SDL的时候要灵活变通不要生搬硬套。**
SDL的执行流程非常厚重如果我们严格按照SDL的标准流程执行在软件开发的每个步骤中加入一定的安全工作这无论对谁都是不小的负担。所以我们要根据公司的实际情况灵活变通。
变通的方法有很多,实现方式上的变通是最常见的一种。我来说几个常见的例子。
* 将安全培训加入到公司定期举办的内部技术交流分享会中。这样一来,既不会因为强制培训的要求引发开发人员的不满,又能提升培训的效果。
* 在制定安全方案的时候,将安全扫描加入到开发提交代码、检测代码质量的过程中,这样就能避免开发人员更改开发流程。
总之实现方式上的变通就是将SDL的各个环节按照开发人员最认可的形式进行灵活的设计和运转提升SDL的落地效率。
**3\. 在SDL的覆盖面上我们也可以有所取舍。**
每个公司都有大大小小的多个业务线让每个业务线都严格遵守这个SDL流程是很难实现的。因此对于一些量级小、敏感数据少的业务我们可以适当降低安全标准。
以开发设计环节为例,我们可以不需要根据具体业务提出具体的安全需求,而是梳理出一份包含常见的安全设计方法的通用列表(包含认证规范、加密标准等)。然后,直接将这个列表发放到开发人员手上,让他们自评。这样既提升了开发人员的工作效率,又降低了我们的工作量。
## 总结
好了,今天的内容讲完了。我们来一起总结回顾一下,你需要掌握的重点内容。
SDL可以从根源上解决安全问题通过加入安全的角色和职责SDL让安全贯穿软件开发的整个生命周期通过事前的培训和事后的应急响应SDL为软件提供了额外的安全防护保障。
尽管SDL非常实用但是它的落地仍然面临很多问题。为了推动SDL落地我们要基于公司已有的开发流程和机制灵活部署SDL。这样我们才能在做出最小改变的情况下仍然将安全贯穿于软件开发的各个流程之中提升公司整体的安全性。
目前安全仍然是一个比较特殊的工作并没有纳入到软件开发的必备工作中去这也是SDL在国内成功案例并不多的一个主要原因。但是我相信正如微软等老牌企业的发展历程一样随着IT行业的不断发展安全工作会和测试工作一样逐渐变成一个必备环节。SDL也会成为各个公司的核心规则制度被大部分人接受。
## 思考题
最后,我们来看一道思考题。
SDL的成功落地需要开发人员的支持和安全人员的高效率工作。你可以思考一下在SDL落地的开发和测试中有哪些工作是可以通过工具来自动或者半自动化地完成的呢这些工具的工作原理又是怎么样的呢
欢迎留言和我分享你的思考和疑惑,也欢迎你把文章分享给你的朋友。我们下一讲再见!