没有任何一家企业认为安全不重要,随之而来的是企业在安全领域进行了大量的资金和人力投入,不过很可惜的是,这些资源更多的是投入到了数据安全和底层的网络基础设施安全领域,甚至到了供大于求的程度,而对于应用程序本身的安全性的投入却严重匮乏。
一个现象是,各大安全厂商乐此不疲的推销各种安全设备、安全服务,宣称其具有立竿见影的效果。不可否认的是,这些设备和服务确实有效果,对缺乏安全能力的企业而言具有不可抵挡的诱惑,但长远来看,企业更应当将资源投入到开发安全,建立起属于自己的安全能力。
安全开发能力不可能一蹴而就,除了需要持续的投入外,也必然会经历一个发展的过程,我们将其进行了梳理并划分为几个不同的阶段,供企业或者开发团队参考,请“对号入座”。
第1阶段:安全质量基本靠运气
团队在产品的分析设计、开发测试以及运维过程中几乎很少,甚至完全没有考虑过安全需求。从产品发布那一刻起,就开始遭受黑客攻击,团队总是忙于应对突发的安全事件。
尽管可能只有极少数团队处于这个阶段,但还是让我们来看看这个阶段团队的一些特征:
- 不清楚有哪些安全实践可以使用,整个开发过程中没有进行安全角度的考量。
- 不熟悉典型的安全漏洞。例如,业务分析师不知道如何分析产品的安全需求;开发人员不知道如何编写代码才能避免引入安全漏洞,缺乏对于常见的安全防御措施的了解;测试人员不知道如何进行安全测试,难以发现潜藏在产品中的安全漏洞。
- 由于团队缺乏安全方面的意识和经验,因此极少使用安全工具或者安全服务对产品进行安全检查。
第2阶段:安全三明治
开发团队逐渐开始意识到安全的重要性,并且有了一定程度的投入。例如,在开发阶段的前期,设立各种安全规范,并且开始有意识的思考安全方面的需求,在产品发布之前对其进行安全扫描。具体做法可能是借助于安全工具的力量,或者直接购买第三方安全服务进行安全渗透测试。
由于这些安全实践的引入,使得一部分较为常见的安全漏洞得以避免,或者虽然代码中存在安全漏洞,但至少有机会通过安全扫描在应用上线之前将其发现并修复。
然而由于这些安全实践大都发生在开发过程的开头和结尾,在开发过程当中并没有多少动作,这样的现象看上去就像是一块三明治,因此我们也形象的将其称之为“安全三明治”。
有相当大一部分开发团队都处于“安全三明治”阶段,尤其是采用瀑布流开发模式的团队。尽管团队对安全有了一定的投入,应用的安全质量有所提高,但“安全三明治”模式依然存在严重的弊端。
“安全三明治”模式中,虽然提到了要在应用开发之前对需求进行安全审查,对技术架构进行安全评审,但经验告诉我们,这些活动多数时候都沦为了一个形式,开发团队只是为了快点交差,并不关注这一活动的效果。
“安全三明治”中的业务和技术安全评审需要以业务需求说明书和技术架构文档作为输入,然而对于处在敏捷转型中(或者已经采用敏捷开发)的团队而言,他们不再编写大而全的需求说明书,转而使用轻量级的故事卡,并且每次只创建出1个迭代(通常是两周时间)的故事卡,而非全部的故事卡。与此同时,技术架构持续在演进,文档上的架构设计早就和实际情况不一致了。“安全三明治”中的业务和技术安全评审则因为缺少赖以生存的“土壤”而难以开展。
开发团队事实上严重的依赖于在开发阶段尾声进行的安全扫描,甚至可以说这是团队对抗安全漏洞的唯一有效手段。然而这个被团队寄予厚望的漏洞扫描却并不完美,它无法暴露出所有的安全问题,无论是安全扫描工具还是人工渗透测试都有其局限性。此外,临近发布才识别出安全问题,会给开发团队制造更多的交付压力,团队很可能会面临两难的选择,任何一种都让团队备受煎熬:
选择一: 推迟发布,直到修复这些安全漏洞。但是,在对速度有极致追求的互联网环境中,这意味着可能错失市场机会,由此造成的损失是团队、企业所难以承受的。更现实的情况是,某些团队的发布日期是固定不可推迟的,几乎没有商量的余地,因此这一选择可能只是理论上成立。
选择二:“带病上线”。选择性的修复部分漏洞,并祈祷其余的安全漏洞不被攻击者发现。但这也许只是个美好的愿望,攻击者以超乎预料的速度发现并利用这些漏洞是大概率事件,团队将再次陷入救火的境地。
处于这个阶段的团队通常具有如下特征:
- 重开头和结尾的“安全三明治”模式,以项目前期的各种安全评审和项目后期的漏洞扫描为主,并不关注应用开发过程中的安全实践。有效果但不尽如人意,且在敏捷转型过程中持续面临阵痛。
- 如果团队中某位成员的安全意识比较强,或者有较多的安全相关经验,那么安全风险就更容易被发现,但如果团队中没有人具备这样的意识或者经验的话,应用的安全就难以得到保证。
- 产品安全质量事实上依赖于安全渗透测试的效果。如果渗透测试发现了安全漏洞,团队还有机会将其修复,但对于渗透测试检测不到的地方,团队也无能为力。
第3阶段:内建安全初级阶段
随着对安全进行持续的投入,团队逐渐抛弃了“安全三明治”式的做法,通过在开发过程中引入更多的安全实践,培养团队人员的安全技能,并且将工具和人工相互结合的做法,使得安全成熟度进入到了第3阶段,其典型特征如下:
- 引入了更多的安全实践,相对于上一个阶段而言更加全面,不再局限于开发过程的开头和结尾。
- 人员的安全技能得到提升。例如,团队能够共同协作,通过一些知识框架或者实践,主动分析应用的安全需求,能识别出明显的安全威胁并制定应对措施。开发人员开始了解并使用安全设计原则,测试人员具备基本的安全漏洞测试能力。
- 能结合工具和人工的力量进行安全测试。例如,测试人员通过工具的辅助执行安全测试。
在这一阶段,伴随着安全测试能力的提升,团队可能会发现更多的安全漏洞,并且伴随着安全需求分析和威胁建模能力的成长,再加上开发过程中的代码安全审查等一系列活动,使得部分安全漏洞或被及时避免,或被消灭于萌芽状态。不过这一阶段也存在着一些不足。
首先,随着技术的发展和创新,开发团队越来越多的利用新技术和新的开发理念去及时的响应业务需求,这些新技术新做法对于一些安全实践而言是巨大的挑战,其难以跟上开发团队前进的步伐。
例如,传统的安全渗透测试需要几天的时间才能完成,并且理论上要求每次产品发布前必须经过安全渗透测试,但是在一个敏捷成熟度较高的开发团队里,他们利用持续交付每天进行多次产品发布是常有的事,这种情况下如何进行安全渗透测试?
其次,安全需要考虑投入产出比,无论哪种安全实践或者活动都是有成本的。随着各种安全实践的增多,安全对于开发团队的牵制也越来越强,会给开发团队带来一定的阻力。在交付压力增大的情况下,团队不可能把大量时间和精力放在无法直接产生经济价值的安全实践上,毕竟按时完成交付永远是第一优先级。
再者,这个阶段虽然大量引入安全实践,但是基本上停留在“一次性”的阶段。例如,通过威胁建模识别安全风险,这样的实践本来是非常有意义的,但是开发团队往往只在项目开头的时候做一次,之后产品功能发生新增和变更的时候,并没有更新威胁列表,以至于产品的安全性随着时间的推移,在一定程度上出现下滑。
第4阶段:成熟的内建安全阶段
处于这一阶段的团队,关注的重点是如何使安全实践更加高效,在降低安全成本的同时,更好的应对新技术、新开发方式给安全带来的各种挑战上面,并且建立良好的安全文化氛围。其典型特征是两个“融合”:
1. 安全和持续交付相互融合。通过大量运用自动化的手段,团队能够在整个交付流程里快速的、便捷的、持续性的获取安全反馈。一些常见的做法如下:
- 使用自动化的静态代码安全检查工具(Static Application Security Testing,简称SAST),在开发人员提交代码之前就进行安全检查,将安全结果直接反馈给开发人员,避免含有常见安全问题的代码被提交到代码库里。
- 在持续构建流水线中利用工具进行自动化的动态安全测试(Dynamic Application Security Testing,简称DAST),发现安全问题后直接让构建失败,将安全结果反馈给开发团队。
- 在单元测试、集成测试、验收测试中加入安全测试用例,对高代码里高风险的部分进行多层次的安全测试,并将其集成到持续构建流水线里,使得开发团队能够持续性的获取安全反馈。
另一方面,如果在生产环境中发现了安全漏洞,团队能够在完成代码修复后,利用持续交付的能力迅速发布到生产环境,而不是被动的等待几周后的下一次发布。
2. 开发团队和安全团队相互融合。安全团队不再扮演守门员的角色,不是开发团队的拦路虎,而是赋予开发团队更多的安全能力,竭尽所能的为开发团队提供安全支持。
例如,安全团队对开发团队中的不同角色进行有侧重点的安全培训,为团队提供或定制开发自动化的安全工具、安全API等等,使得团队能够以自助式的方式利用这些工具和资源。另一边,开发团队则逐渐开始学习通过轻量级的威胁建模等手段主动识别并分析安全风险,主动了解团队所使用的开发框架中的安全特性并加以利用。某些企业中,开发团队中的工程师甚至还会定期的和安全团队中的工程师进行相互轮换,以进一步加强两者的融合。
处于这一阶段的团队,安全实践已经全面融入到了他们日常工作当中,能以更快的速度,更便捷的方式,持续性的为团队提供安全质量反馈,开发团队基于这些反馈迅速做出调整。与之相伴的是浓厚的安全文化氛围,高度认同安全是产品质量不可或缺的一部分,提高产品安全性是每位团队成员的职责。
总结
每个团队的实际情况不尽相同,虽然我们将安全成熟度划分为几个阶段,但是每个阶段之间并没有非常明显的界限,有可能团队正好处于两个阶段之间的过渡状态。我们建议团队根据自身的实际情况,综合评估自己当前的安全成熟度,并以此为出发点,为达到更成熟的级别而努力。
安全成熟度的目标不是给开发团队罗列一大堆的安全实践,而在于为开发团队指出前进的方向。无论团队最终采取何种实践、工具、流程等,核心的目标都应当是在开发过程中尽早,尽快,持续性的考虑安全。