内建安全的软件开发

1. 传统安全实践面临着严峻的挑战

随着互联网应用、移动应用爆发式的增长,伴随而来的黑客攻击事件也是层出不穷。仅在过去的2015年里,被公开报道的数据泄露安全事件就有约3930起,将近7.36亿条数据被泄漏。显而易见的是,如果某家企业被爆出安全问题,对企业造成的影响不仅仅只是名誉、财务上的损失,还会遭受法律诉讼,陷入竞争不利的局面。安全已经是企业不可忽视的问题。

近年来,黑客攻击的趋势已经发生了显著的改变,由最初的针对网络、操作系统以及服务器的攻击,已经转变为针对应用程序的攻击。根据Garnter的调研报告显示,有将近80%的安全漏洞发生在应用层。为了应对新的安全威胁,企业也做出了各种尝试,例如为员工提供安全培训、设立安全规范文档、部署Web应用防火墙、建立安全监控中心、利用安全渗透测试寻找安全漏洞等等。经过一些列的努力,取得的成果也是比较显著的,例如老生常谈的SQL注入攻击,其全球范围内的漏洞数量呈现出了非常显著的下降趋势,如图1-1所示。

image_0

图 1-1 SQL 注入漏洞数量趋势

然而并不是所有发生在应用程序中的安全漏洞的数量都得到了有效抑制,例如跨站脚本攻击漏洞的数量似乎并不受安全措施数量的影响,如图1-2所示。

image_1

图 1-2 XSS 漏洞数量趋势

一个现象是,企业为应对应用安全问题采取了各种措施,虽然有一定成效但是也有或多或少的问题,如图1-3所示,随着安全措施数量的增加,应用中的安全漏洞的数量不再显著减少。似乎无论如何努力,开发出来的应用中始终有安全漏洞。

image_2

图 1-3 安全措施和安全漏洞数量的关系

除此之外,企业还面临着更多的困境:

  • 安全漏洞总是很晚才被发现出来,造成的结果是安全漏洞的修复成本高昂。
  • 未能检查出隐藏在应用中的安全漏洞,含有安全缺陷的应用被发布到生产环境中,这将增加企业面临的安全风险。
  • 某些安全措施容易被误解为是团队的负担
  • 开发团队人员安全技能有所缺失,应用的安全性过度依赖于应用安全团队

2. 为何安全漏洞如此难以消除?

为消除安全漏洞,企业采取了不少措施,然而一个不争的事实是,企业主要依赖于Web应用防火墙(Web Application Firewall,下文简称WAF)和渗透测试(或安全审计)。然而问题在于,这两种措施固然有效,但是也存在着明显的不足。

2.1 WAF是把双刃剑

WAF主要的职责是阻挡攻击,为开发团队争取修复漏洞的时间。换言之,只要应用中存在安全问题的代码没有被修复,漏洞就会一直存在,一旦WAF规则被绕过,或者配置不当,反而会将应用置于更高的安全风险当中。此外,误报和漏报始终是WAF无法彻底解决的问题,与此同时,随着应用规模的扩大,业务逻辑复杂度的增加,对于WAF的管理维护难度也在不断增加。

2.2 渗透测试让企业面临两难的境地

渗透测试确实能发现安全漏洞,但是也存在着明显的不足。首先是太晚才能得到安全问题的反馈,因为通常而言,渗透测试会被安排在产品上线发布之前进行,此时如果检查出安全漏洞,企业反而会面临两难的境地:修复安全漏洞之后再发布产品,或者强行发布包含安全漏洞的产品。同修复业务缺陷一样,修复安全漏洞也是越晚修复成本越高,开发团队需要投入更多的时间和人力,而这可能导致产品推迟发布,错失市场机会;如果强行发布含有安全漏洞的产品,又将增加被黑客攻击利用的风险。

2.3 抛开现象看本质,问题的根源在于缺乏高效的安全反馈机制

应用中的安全漏洞是在开发过程当中由于各种原因被引入的,然而回顾现有的安全措施就会发现,其中大量的措施发生在应用程序开发过程之外,例如WAF、安全监控发生在产品上线之后,渗透测试需要等待开发完毕后才能进行,而安全培训、安全规范只能起到预防作用。尽管各种安全措施都能为开发团队提供不同程度的安全反馈信息,然而问题在于,大量的安全措施都发生在开发过程之外,距离安全问题被引入的时间点之间有很长的距离,因此安全问题不能及时的反馈给开发团队。

此外,由于不少安全措施的成本高、耗时长,因此难以持续性的为开发团队提供安全反馈。例如聘请第三方安全公司对应用进行安全渗透测试的价格较高,且往往需要几天甚至更多时间才能收到安全报告。

3. 更好的解决安全问题

安全漏洞本质上是软件质量缺陷,安全性是软件质量的重要组成部分,而现如今应用安全面临的问题和多年以前软件测试面临的问题极其相似。当时人们在开发软件的时候,采取的做法往往是在软件开发临近结束之时集中性的进行测试,修复发现的质量缺陷,结果是当时的软件质量普遍不高,不少项目因此失败。

为了提高软件质量,开发团队采取了一些措施,例如将测试介入的时间点提前,尽早进行测试,甚至是先写测试后写实现代码,与此同时也大量采用自动化测试来加快测试执行速度,采用构建流水线持续关注软件质量,并且每位团队成员都对软件质量负责,而不再认为只是测试人员的职责。这些措施之所以能够显著提高软件质量,关键在于它们能够更加高效的为开发团队提供软件质量相关的反馈信息,使得开发团队能够基于反馈结果迅速进行改进。

同理,要更好的解决安全问题,开发团队应当建立起一个高效的安全反馈机制,在开发过程中引入一些安全活动,尽早开始收集安全反馈信息,加快获取安全反馈的速度,在整个开发过程中持续性的关注应用的安全性,与此同时团队成员共同来承担安全职责。我们将这些在实践中总结出来的经验命名为内建安全的软件开发方式(Build Security In DnA,下文简称BSI),从源头上尽早、尽快、持续性的,以团队共同协作的方式发现并解决安全问题。

image_3

图 3-1 内建安全的软件开发方式 (Build Security In)

3.1 尽早获取安全反馈

越早获取到安全反馈信息,越有利于开发团队以更低的成本将其修复。一个反面例子是,安全问题在早期就已经引入了,但是只能通过后期的渗透测试才能暴露出来,安全反馈信息经历了很长一段时间才能反馈给开发团队。与其依赖于后期的渗透测试,不如在开发过程当中引入一些适当的安全实践,比如在分析业务需求的同时主动分析安全需求,将其作为质量验收标准在团队内明确出来,再比如,针对每次代码提交都对其进行安全评审、测试人员在测试业务功能的同时还对安全性进行验证。通过这种方式,使得团队能够尽快得知应用的安全状况,而不必依赖于很晚才能提供安全反馈的渗透测试。

image_4

图 3-2 在开发过程当中引入安全实践

3.2 通过自动化加速获取安全反馈的速度

从安全角度对代码进行的评审,以及测试人员主动进行安全测试等等手段都能更早的产出安全性的反馈信息,但是传统的安全测试、渗透测试主要是以手动的方式进行,造成的结果是需要耗费许多时间才能收集到安全反馈信息。更好的做法是,对于常规的安全测试可以借助工具以自动化的方式进行,不仅能够以更快的速度得到安全性反馈,还能在一定程度上弥补由于人员安全技能不足所造成的安全测试不够全面的问题。自动化带来的另外的好处是,它可以集成入CI服务器,从而让开发团队可以在CI流水线完成之后第一时间发现应用的常规安全问题,而不必等到上线前由安全专家来发现安全问题。

例如,应用通常依赖于各种第三方组件,这些组件可能含有已知的安全漏洞,手工对每个组件进行安全检查是行不通的,更好的做法是利用自动化的检查工具如OWASP Dependency Check,以更快的速度对组件进行安全检查并且生成结果报告。这一过程是完全自动化的,开发团队只需定期检查报告即可,使得开发团队获取反馈的速度得到极大的提升。

3.3 在开发过程中持续性的关注安全

收集安全反馈不是一次性的活动,高效的安全反馈机制和持续集成秉持相同的理念:除了尽早集成、尽快集成之外,很重要的一点就是让集成活动能够持续性的发生。类似的,对于建立高效的安全反馈机制而言,在能够尽早、快速的获取安全反馈的同时,还需要让这个反馈循机制在应用开发过程中持续的运行下去。

自动化使得开发团队能够更容易的做到对安全的持续关注。例如,将自动化的代码安全扫描和持续集成服务器结合起来,这样在每次代码提交后都能得到一份安全报告,从而可以立刻着手进行相应的修复。此外,对于那些不适合自动化运行的安全实践而言,开发团队依然有必要持续性的去做。例如,每当应用的功能发生变更之时都应该进行一次威胁建模以分析安全威胁,明确安全需求,每当新的功能被开发出来,测试人员都要对其安全性进行验证。

image_5

图 3-3 对安全保持持续性的关注

3.4 团队成员共同承担安全职责

大多数人认为团队中的测试人员应该对产品的安全负责,理由是他们要进行各种测试,安全测试理应包含在内。如果有专门的安全团队,则更多的人会认为安全团队应该主导产品的安全性,毕竟,在他们眼里这是安全团队天生的职责。

但这是一种误解,只要人们认为安全应该由团队中的某个角色或者某个独立的团队负责,就容易形成消极的氛围:既然有专门的人在负责产品安全,那就说明安全不是自己的职责,等发现安全问题了再说。这种氛围会带来很多负面影响,例如:安全问题难以及早发现并解决,人员安全技能得不到锻炼,安全改进在团队内难以推动,等等。

和传统的高度依赖于某个角色或者安全团队来保证产品安全的做法不同,BSI则是把安全职责拆分到团队中的每个角色身上,让所有人都参与进来,共同协作解决安全问题。每个人都肩负着维护产品安全性的责任,主动为此付出努力。

业务分析人员在分析业务需求的同时把产品的安全性纳入考虑的范围之内,如果他们没有相关的安全技能,则可以和技术人员合作共同来完成这一任务,与此同时,开发人员在编码的过程中有意识的去避开安全风险,并协助测试人员对产品进行安全测试。在产品交给安全团队进行安全审查之前,一些安全漏洞已经被发现并修复了,甚至在需求分析之时就已经被规避了。此时的产品已经具备了一定的安全性,也为安全团队争取到了更多的时间,使得他们可以把更多的精力放在检测深层次安全漏洞上面。

通过这种共同分担职责的方式,开发团队在应对安全问题上的内部凝聚力会得到增强,团队成员会更有意愿和动力去提升自己的安全能力。更重要的是,这种做法可以使得团队成员以及安全团队能更好的进行协作,从而逐渐形成良性循环。

image_6

图 3-4 共同承担安全职责

4. 总结

安全,是每个企业都需要做到的,在互联网时代更是重中之重。企业正面临着全新的安全挑战,然而现有的一些传统安全措施却并不能高效的解决这些问题,主要的原因在于过度依赖WAF、渗透测试等被动防御手段,往往是在比较晚的时候才获取的安全反馈,导致安全问题修复成本高昂,甚至使企业陷入进退两难的局面。

为了提高应用的安全性,并且弥补传统安全措施的不足,Build Security In应运而生:在软件开发过程中引入合适的安全实践以尽早发现安全问题,利用自动化的优势缩短安全问题的反馈周期,持续的、以共同协作的方式主动预知并化解安全问题。在减轻开发团队和安全团队负担的同时,提高发现、解决安全问题的效率。

安全不是绝对的,所以BSI对于安全的保证也是相对的,但是对于业务越来越复杂,规模越来越庞大的软件系统,BSI这种内建安全的软件开发方式必将从源头上减少安全风险,降低被黑客攻击的可能,从而显著减少系统在上线使用后因安全问题造成的损失,使其在互联网的大潮中生存下来。

内建安全的软件开发,首发于文章 – 伯乐在线