1.源码安全回顾
在工具的帮助下,很多安全漏洞都可以被自动化的扫描出来,但还是有一些安全问题目前还是只能依靠人工来检查发现,例如权限控制、业务风险。因此,在每日代码评审(Daily Code Review)的时候,如果团队能够对源码从安全角度进行一次回顾或者检查,那么必然更有助于尽早发现安全问题,降低问题修复成本,最终确保应用程序的安全质量。
通过人工去检查源码中是否有安全漏洞的这个活动,传统上叫做“代码评审”,但“评审”这个词给人一种过于严厉的印象,仿佛突然空降一个联合专家组对程序员小张写的代码展开细致而周密的审查,一旦查出问题来立马就对小张进行处罚,轻则口头警告重则直接辞退。事实上这个活动并非如此,只是“评审”二字确实容易产生误会因此遭遇抵触。而我更愿意把这个活动叫做“源码安全回顾”,类似于做复盘,大家聚到一起,回过头来看一看过去一段时间(通常是当天)团队写下的代码,看有没有安全问题,有就改之无则加勉,仅此而已。
源码安全回顾确实有必要,但这个活动在实际执行中也面临着一些落地难的问题:
- 团队成员若缺乏安全意识,根本不会意识到还需要人工对源码的安全性进行回顾检查,因此这个活动不会得到执行;
- 那些有安全意识的团队成员,对于具体应该检查哪些安全要点、检查得是否足够全面没有十足的把握,容易出现遗漏;
- 团队成员的注意力通常会高度集中在代码对于业务场景的技术实现上,容易忽视对源码的安全性进行检查。
源码安全回顾落地实施过程中遭遇的这些问题,在航空业有相似的的情景,他们的成功经验或许值得我们借鉴。
2.航空业以血泪换来的经验
在地面和空中飞行过程中,飞行员的任务都十分繁重,需要检查很多重要的飞行参数,与此同时还要进行众多重要操作,这些操作的顺序和时机都很重要。如果有其中一项重要参数没有检查到,或者没有实施某个必要的操作,那么将对飞行安全造成严重影响。
比如说,2006年,N600XL号航班的飞行员因不熟悉所飞机型,误关应答机而没能发现,结果撞上了迎面飞来的巴西戈尔航空公司的1907号航班,前者翼梢小翼折断后成功紧急迫降,而后者则因左翼被折断而连续翻滚11次后在空中解体,机上154人全部遇难。
1997年的6月22日,俄罗斯勇士表演队一架苏-27战机在飞机降落时忘记放下起落架,导致飞机的武器挂架和腹鳍着地。好在此次事故有惊无险,飞机在跑道上滑行了几百米后后停了下来。
在很早以前,在航空业还没有飞行检查清单以及标准操作程序(SOP,Standard Operating Procedure)的时代,飞行安全事故发生的概率相对较高,主要原因之一在于每位飞行员的驾驶风格、习惯各不相同,有些飞行员操作十分谨慎,而有些则大大咧咧,从而为航空安全事故埋下安全隐患。后来航空业大力推行了飞行检查清单、标准操作程序,不管飞行员是谁都需要根据标准来进行操作,彻底规范为了飞行员的行为,显著降低了安全事故概率。
3.情景相似性
航空业和源码安全回顾所面临的难题有一定的相似性:
不知道
- 飞行员:所飞机型的应答机容易被误关,不知道需要持续检查应答机状态
- 程序员:不知道需要对源码做安全回顾
有遗漏
- 不知道:忘记放下起落架
- 程序员:忘记做源码安全回顾、安全回顾不彻底不全面
在安全检查清单和标准操作程序的帮助下,应答机状态异常或者起落架没有放下大概率将被及时发现,事故将可以避免。同理,如果软件开发领域也有一份确保安全的检查清单,或者标准操作程序,可以用于源码安全回顾环节,那么开发团队也将有机会及时的、正确的开展这项活动,源码中的安全漏洞被检查出来的概率也将得到提升。
4.一份建议的源码安全回顾检查清单
下面这个是我根据多个开发团队的实践经验总结得到的一份源码安全回顾检查清单,涵盖的范围仅限于应用程序。通常在每次代码回顾(Daily Code Review)的时候使用,当然也可以在其他时候执行,例如代码提交到代码仓库、Pull Request Review、某个固定时段(例如每周3下午)。
与此同时,需要补充说明的是,每个团队的业务技术上下文有所不同,检查清单的内容自然也各有差异,团队可以根据自己的实际情况来定制内容。此外,清单仅起提醒作用,团队仍需具备足够的安全能力才能很好的执行清单内容。也就是说,清单解决的是“应该检查什么”的问题,而不是告诉团队“如何做检查”。后者是各种安全指南文档、安全培训要解决的问题。
如果你想定制一份检查清单,下面这些点是需要注意的:
- 清单内容应该尽量精简,精简到团队可以在2分钟时间内执行完毕清单里的所有内容
- 如果是工具就能检查出来的安全问题,就不必再人工重复检查,只需检查工具检测的结果即可
- 尽量通过人工检查去发现那些高风险,却又不能很好的通过自动化工具检查出来的安全问题,例如权限控制
- 如果能把检查各安全工具的过程通过脚本来进行自动化,那么清单中编号为1-3的条目可以进一步精简为: