1.2 软件中的安全问题
软件安全(即设计、建造和测试安全的软件的方法)通过确定和解决软件本身的问题而触及了计算机安全的核心。软件安全试图基于这种方法建造能够主动地抵御攻击的软件。
1.2.1 缺陷和瑕疵还有缺点,哦,天哪!
虽然图1-1清楚地表明软件问题是一个大问题,但是,在对软件安全问题进行分级和分类方面,科学家们做的工作还很少。
从强调安全的角度来重新介绍基本的术语——缺点(defect)、缺陷(bug)、瑕疵(flaw)和风险(risk)——有助于澄清分类问题。我建议对这几个词采用如下的用法。
缺点:软件在实现上和设计上的弱点都是缺点。缺点是一种可能在软件中潜伏许多年,仅仅在某个应用背景的系统中才会表现出来并导致严重后果的问题。
缺陷:缺陷是实现级上的软件问题。缺陷可能存在于代码中而永远不会被执行。虽然术语缺陷被许多软件业者所广泛使用,但是我限制这个术语的使用范围,仅用它来描述相当简单的实现上的错误。缺陷是很容易被发现和修改的实现级问题。下面的文本框中提供了一个缺陷的示例——(被过分渲染的)缓冲区溢出:一种实现缺陷。
在检测由低级和中级的实现缺陷引起的安全弱点方面,研究人员已经取得了很大的进步。早期的研究工具有FIST [Ghosh,O'Connor和McGraw, 1998],ITS4 [Viega等,2000a],Jscan [Viega等,2000b],Splint [Evans等,1994],Metal [Engler等,2000],以及Prefix/Prefast [Bush,Pincus and Sielaff 2000]。从2005年开始,商业工具(例如,Fortify Software的Source Code Analyzer)也在市场中出现,而且这类工具的开发还在继续快速进行。这类工具对于检测大范围的实现缺陷,包括缓冲区溢出、格式化字符串、资源泄漏和简单的竞争条件是非常有效的——所有这些都仅仅依赖于有限的代码分析和对外部环境的知识。(关于代码审核和静态工具的使用方面的更多信息,参见第4章)
瑕疵:瑕疵是一种更深层次的问题。与数组引用中的差一错误或者使用不正确的系统调用这样的简单的错误相比,瑕疵通常更加难以察觉。瑕疵当然是在软件代码中被实例化的,但是它也出现(或者不出现)在设计级中。例如,大量的典型瑕疵存在于错误处理和恢复系统中,它们都会导致程序不安全或者无效率。可以在后面的文本框“Microsoft Bob:一个设计瑕疵”中看到另一个例子。自动地检测设计级中的瑕疵的技术现在还不存在,尽管人工风险分析能够识别瑕疵(参见第5章)。
1被过分渲染的缓冲区溢出:一种实现缺陷
表1-2提供了缺陷和瑕疵的一些简单例子。在实践中我们发现,软件安全问题中的缺陷和瑕疵各占一半。这说明,通过代码审核来清除缺陷只能解决一半的问题。对于那些认为软件安全仅仅是编码问题的人来说,这可能会让他们大吃一惊。显然,软件安全并不仅仅与编码有关。Microsoft报告说,在他们正进行的安全推动活动所揭示出来的问题当中,有超过50%的问题实际上是属于体系结构的问题[Mike Howard,私人信件]。Cigital的数据显示,瑕疵类型的划分比例是60/40,这说明Cigital在体系结构风险分析上更胜一筹。
表1-2 缺陷和瑕疵的例子
缺 陷 瑕 疵
缓冲区溢出:摧毁堆栈缓冲区溢出:一站式攻击缓冲区溢出:格式化字符串攻击竞争条件:TOCTOU不安全的环境变量不安全的系统调用(fork(), exec(), system())不正确的输入验证(黑名单和白名单) 方法覆盖问题(子类化问题)设计中的分区问题特权块保护失败(DoPrivilege())错误处理问题(打开出错)类型安全混淆错误不安全的审核日志设计被破坏或者非法的访问控制(层间的基于角色的访问控制[RBAC])签署了太多的代码
软件安全缺点可分为两种基本类型,每一种各导致了大约50%的软件安全问题。
1Microsoft Bob:一个设计瑕疵
这是一个常常听到的故事,可能是杜撰的,但是很有趣,而且我们能从中得到有益的教训。 E中确实包含一个设置系统密码的工具。当程序认为用户忙于做其他事时,Microsoft Bob就开始工作(就像Word中的曲别针助手Clippie)。Bob最 不安全的功能在于当用户试着输入了三次(不正确的)密码时,Bob将弹出如下的信息:“我想你忘记了你的密码,请输入一个新的密码。”然后,就允 许用户修改密码,即使他不知道老密码。Microsoft Bob,黑客之朋友。 |
风险:瑕疵和缺陷会导致风险。风险并不是失败。风险表明瑕疵或缺陷影响软件效果的概率(即风险=概率×影响)。风险衡量还必须考虑可能出现的潜在破坏。高风险不仅可能出现,而且还可能导致巨大的破坏。可以通过技术和非技术的方法来管理风险。
建造安全的软件就像建一栋房子。我把正确的底层编码(比如使用可能导致缓冲区溢出的函数)比喻为使用坚固的砖块而不是用锯末做的砖块。对于房子的完整性来说,所用的砖块类型是非常重要的,但更重要的是(如果盖房子的目的是为了将不好的东西排除在外),在设计中包含四面墙和一个屋顶。软件也是一样:使用了哪些系统调用和哪些库以及如何使用它们是很重要,但是整体的设计性能经常取决于更多的方面。到现在为止,软件安全过多地关注砖,而忽略了墙。
| 回书目 上一节 下一节 |