主要结论
- 很少有工程师被问及自己的软件是否安全,但几乎每个系统都有某些潜在的安全隐患。
- 物联网设备的激增将潜在的攻击面和可能造成的损失类型无限放大。
- 安全的,和不安全的软件之间的差异可能很不容易察觉。
- 包括 FTA、STAMP,以及 UML 状态机等多种分析技术可以帮助我们找出系统中可能存在的失效路径。
- 无需等待最完美的解决方案,任何可以改善系统安全性的技术都是有价值的。
在我的职业生涯中,我只从一位员工和咨询的客户处听到过这个至关重要的问题:这个软件安全吗?
在我们的方法论大战中,我们在特性、规模、特点、技术需求、测试方法等方面付诸了太多精力,以至于很少有人关注我们的成果是否足够“安全”。
安全的软件产品,应当:
- 不会导致财产、经济,或数据损失。
- 不会对人员或其他生物造成身体、情绪,或声誉方面的伤害。
- 能够抵御可能导致上述第 1 和第 2 条所诉情况变为现实的恶意行为所造成的安全威胁。
当前状态
2015 年 7 月,白帽黑客 Charlie Miller 和 Chris Valasek 入侵了记者 Andy Greenberg 所驾驶的一辆 2014 年款吉普切诺基。当时 Greenberg 正以每小时 70 英里的速度驾驶着这辆车,Miller 和 Valasek 坐在距离车辆 10 英里远的地方成功操作了这辆车的空调、广播、仪表盘显示器,激活并恢复了车辆的制动系统,最终让这辆车彻底停了下来。Greenberg 的报道受到广泛关注后,菲亚特·克莱斯勒召回了 140 万辆切诺基,令人尴尬的是,仅仅两个月后,他们又一次因为安全性欠佳的 Uconnect 组件再次召回了 8000 辆 SUV。
Security Affairs 网站收集整理了有关汽车被入侵事件的所有新闻报道。很多业内专家认为,机动车制造商的软件安全意识远远落后于整个软件行业,作为一名软件工程师,我对于这种观点倍感担忧。负责机动车安全性测试的 Security Innovation 公司研究员 Ed Adams 曾说:“机动车制造商已经远远落后于时代。车载软件的开发并不像,例如银行用软件,甚至微软开发的软件那样使用相同程度的安全标准。”
随着物联网技术突飞猛进,我们开始面临全新的,同样令人恐慌的弱点,以至于事后可能会问:“为什么没人预计到会出现这种情况?”Kaspersky Lab 的 Sergey Lozhkin 曾介绍过针对医疗设备进行的一些令人印象深刻的入侵。以医疗设备为工作重点的 Lozhkin 主要研究医疗设备到底有多脆弱。他曾经选择了一家目标医院,然后说:“我测试了医院的 WiFi 网络,最后成功连接到一台 MRI 设备,从中获得了个人信息和软件架构中包含的 [缺陷]。这一切让我感觉惊恐,因为整个过程太顺利,太容易了。初始攻击是通过 WiFi 网络进行的,对于一个存储了各种医疗数据的网络,他们的网络安全性实在不堪一击。”
在以悲观的展望作为结尾的报告中,Lozhkin 说到:“白帽安全研究人员和有恶意的黑客都在积极探索这些领域:汽车劫持、车联网、医疗设备,以及其他一切。对于网络罪犯来说,这是一片足够大的市场。”
安不安全并不容易察觉
希波克拉底誓言(Hippocratic Oath)里说过:“首先,不要造成伤害(Above all, do no harm)。”但安全问题并不容易察觉。由于网络延迟消息需要发送两次,向数据库执行了单阶段提交(One-phase commit):这些情况通常被我们视作技术问题,直到我们发现这些消息是在为一些对剂量控制极为严格的药物下单,或者数据库已经在未被察觉到的错误状态下持续运行了很长时间。将对象与状态变量一起存储在数据库中已经成为一种普遍的情况,如果数据库中的这些变量有变化,所还原的对象也可能会处于未定义的状态之下。
进行更完善的测试,这只是塑造更安全的软件过程中的方法之一。对安全问题采取积极主动的验证,这样的心态更重要,但我们又该如何决定软件中是否存在弱点?
方法并非总是显而易见的,而我们的看法会受到“脑洞不够大”的蒙蔽。例如,一个文字处理软件能造成什么损害?
假设你在文字处理软件中创建了下面这样的一份文档,其中的“<\t>”符号代表制表符(Tab)。
保存该文档,稍后再次用这个字处理软件打开,发现文档的内容变了:
有一个制表符消失了。嗯,这能造成多大危险?答案取决于原始内容最开头的一行内容。表头内容对应的不同列是通过制表符分隔的,加上表头后,“实际的”文档内容是这样:
译注:表头三个字段的内容分别为:囚犯姓名;绞刑;释放
对不住啊 Chester!这个问题我们准备在下一版中修复!(这个例子来源于美国海军有关文档保真度的测试规划,出于简化的角度考虑,我把这个场景进行了略微的修改。)
现实世界中的解决方案
为确定安全性,我们不能只依赖对产品代码本身进行的测试。缺陷的数量和安全性之间并没有直接联系。零缺陷并不意味着软件绝对安全,因为“缺陷”是通过与所规定行为之间的关系界定的,而我们的规定本身可能并不正确。也正是因此,很多缺陷才会让人吃惊,“这到底是怎么回事?”,“这种问题不应该出现啊!”,或者“我从没想到竟然会这样!”
我们可以在自己的产品开发过程中使用一种名为故障树分析法(FTA,Fault Tree Analysis)的分析技术。FTA 可以对系统中能够导致组件出现可预见但不希望出现的损失或失败的事件或路径创建可视化模型。从概念上来讲,故障树分析法可以帮助我们发现不安全或不希望出现的最终状态,并可通过建模器反向指定用于生成最终状态的条件。
FTA 使用标准的布尔逻辑(AND、OR、XOR)等概念作为“门户”。传入这些门户的路径和事件将用于生成不希望出现的状态所造成的结果。下面的例子展示了“剧烈头痛”的目标状态以及可能导致这种情况的原因。
FTA 是一种强大的技术,很适合用于最终状态已知情况下的整个设计流程,这种技术基于一种失败始终源自硬件或软件组件故障的哲学体系。任何技术人员均可以相当容易地创建故障树示意图,Microsoft Visio 还提供了一个 FTA 模板插件。我发现将故障树示意图与 UML 状态机示意图配合使用,可以帮助我们更好地理解我为客户开发的产品中可能遇到哪些问题。
软件安全专家 Nancy Leveson 创建了一种用来补充和取代 FTA 的技术:STAMP(系统- 理论事故模型和流程,System-Theoretic Accident Model and Processes ),这种技术主要专注于系统整体以及不同组件之间的交互,而非只专注于特定组件本身。Leveson 认为,失败总是出现在系统处于危险状态时,而系统处于危险状态通常是因为未能对系统行为强制实施必要的安全约束。
由于对系统采取了整体化系统视角,STAMP 并不像只须绘制示意图的故障树那么简单。STAMP 针对不同程度的诱因提供了丰富的语义和多角度支持,包括事件链、因果条件,及造成故障条件的系统级原因等。由于STAMP 还可包含约束、不同层次程度的控制,以及流程模型,因此不仅可用于软件开发领域,还可用于产品开发和交付过程。
这和我的Web 应用有什么关系?
软件产品的开发已不可避免地从单机应用程序发展为需要交付由多个相互交互的功能单位组成的,使用多种语言开发,同时运行在不同公司或组织提供的多个平台上的所谓的“软件”。我们身处于一种“多层架构系统(Systems of systems)”的世界中。通过接口进行交互的做法极为普遍,但都有可能造成失败。我们应当拥抱各种能帮助自己更清楚认识到自己所开发软件的安全性的工具。
有关安全的顾虑使得我们在发布过程中必须满足各种规范的需求,为了缓解这些顾虑,我们不应等待有朝一日才会出现的完美答案:在致力于实现更高安全性的过程中,就算“零敲碎打”的方法也值得考虑。
UML 状态机示意图可以帮助我们发现危险的,或可能造成错误的状态或状态变化。例如当程序员不知道具体需要执行哪个逻辑时,就会进入一种“Catch all”的状态。当组件处于这种预设的状态后,会产生导致进行错误处理的事件或消息。
多线程的枚举总是会遇到问题。我们需要尽量通过全面的分析确定关键区域,产生竟态条件的可能性,以及出现死锁或其他多线程异常的可能性。
当代码检测到错误后,是否需要关闭线程、进程,或应用程序?还是以降级模式继续运行?我们应当从安全性的角度总结出每种可行决定的对应收益和风险。
现代化应用程序的复杂性可能会让人难以置信,虽然整个行业最近才开始面对可联网汽车和医疗设备的劫持等负面报道,但一些软件产品早就被“杀死”了。
二十世纪八十年代,软件行业首次遭遇臭名远扬的致命软件故障:Therac-25。这款医疗诊断仪器将六位病人暴露在过量的 X 射线辐射之下。
Therac-25 的悲剧是很多因素共同作用造成的,包括:
- 重复使用上一代产品 Therac-20 中的软件。
- 用户界面输入字段的相关改动未能注册至控制子系统。
- 竟态条件。
- 纯软件形式的控制方式,未包含硬件锁定装置。
六位遭受过量辐射的病人中,三人由于该仪器的过量辐射而死亡。
这种悲剧是缺乏测试导致的吗?根据 Leveson 的介绍,制造商已经进行了非常全面的测试,但也许他们的测试本身是错误的。软件测试主要会通过硬件模拟器进行。人们通常趋向于假设如果软件中不包含 Bug,那么软件就是安全的,但这种结论本身就有问题。在她的报告中,Leveson 对于在 Therac-25 中使用 PDP-11 汇编码的说法就算在今天依然适用:
最基本的错误包括贫乏的软件工程实践,以及所生产的仪器仅能通过软件实现必要的安全控制。此外比具体的代码错误更严重的是软件整体所采用的不安全的设计方针。
上述陈述中最令人不安的部分在于,对于当今一款典型的软件产品,其软件整体设计早已超越了我们精确理解的能力。我们正在面临一种悖论。在敏捷开发中,为了更好地理解需求、设计,以及代码的正确执行过程,我们会交付多个小规模的功能块。但在将每个功能块加入上一代产品后,多层架构系统的交互将会以指数形式增长,进而削弱我们对所交付内容的理解和信任。
“成熟”不能一蹴而就
FTA、STAMP,以及 UML 等模型是可以帮助我们创建更可靠系统的工具。业内的各种故障报告建议我们除了功能的正确性,还应当对产品的安全性进行更为积极主动的尽职调查。存在弱点的可无线联网机动车,暴露到医院开放网络中的医疗设备,会广播父母交谈内容的婴儿监视器,可访问互联网并让黑客听到你说了什么的智能电视… 为了让数字化世界变得安全哪怕一点点,我们都要付出艰巨的努力。
关于本文作者
Gary K Evans是一位敏捷转型顾问,18 年来已帮助很多团队和组织顺利采用了敏捷方法。他已获得 Scrum Master 认证、SAFe 4 Program Consultant 认证,以及 Design Patterns 专家认证,为数十个使用 Scrum 和极限编程(Extreme Programming)的项目提供了指导。他曾在数十个软件大会上发表讲话,在一本软件开发杂志担任了 6 年的特约编辑,并担任 Jolt Awards for Software Productivity 活动裁判 14 年。他是 UML、面向对象的分析和设计、用例、等领域公认的专家,曾是 Alistair Cockburn 的合伙人。他曾编写过数十套培训课程,涵盖务实业务分析、敏捷项目管理、Scrum 敏捷开发、务实用例撰写、面向服务的分析,以及面向对象的分析和设计等领域。
作者: Gary K. Evans ,阅读英文原文: But is it Safe?
评论