首页>参考读物>计算机科学与技术>软件工程及软件方法学

安全编程代码静态分析
作者 : Brian Chess;Jacob West
译者 : 董启雄 韩平 程永敬
丛书名 : 华章程序员书库
出版日期 : 2008-03-25
ISBN : 7-111-23321-3
定价 : 56.00元
扩展资源下载
扩展信息
语种 : 简体中文
页数 : 362
开本 : 16开
原书名 : Secure Programming with Static Analysis
原出版社:
属性分类: 店面
包含CD :
绝版 : 未绝版
图书简介

创建安全的代码,仅有好的意图是远远不够的。程序员要知道:他们的代码几乎需要在各种使用环境和各种配置之下都是安全的。静态源代码分析为用户提供了使用优秀的工具来审查其工作的能力,从而找出各类可直接导致安全漏洞的错误。现在,本书提供了一份关于静态分析的完整指导:如何进行静态分析,如何将其集成到软件开发过程以及如何在代码安全审查期间最大化其功效等。
  静态分析专家Brian Chess和Jacob West探讨了当前最为常见的安全缺陷类型。他们使用来自实际安全事件的Java和C代码实例阐明了:如何发现编码错误,如何防止出现编码错误以及如何通过静态分析来快速找出类似的错误。本书读者对象是所有关注构建更加安全的软件的人:软件开发人员、软件安全工程师、软件分析师以及软件测试人员。

  本书内容包括:
  ■ 为什么常规的Bug捕获技术经常找不出安全问题。
  ■ 怎样才能通过静态分析帮助程序员做好安全工作。
  ■ 决定一个静态分析工具成败的关键属性和算法。
  ■ 提高代码静态分析效率的36种技术。
  ■ 70多种严重安全漏洞及其详细解决方案。
  ■ 来自FireFox、OpenSSH、MySpace、eTrade、Apache httpd以及其他更多软件的漏洞实例。
  ■ 处理非可信输入的技术。
  ■ 消除缓冲区溢出的战术和战略方法。
  ■ 避免出现Web应用程序、Web 服务以及Ajax相关的错误。
  ■ 关注安全的日志技术、调试技术以及错误/异常处理技术。
  ■ 秘密和机密信息的创建、维护和共享。
  ■ 带你穿越静态分析的详尽过程。

  “为了能够对Java进行静态分析,我们对其进行了相关设计。本书向您展示了如何应用高级静态分析技术来创建更为安全、更为可靠的软件。”
                     ——Bill Joy(Sun Microsystems公司的共同创始人、Java语言的共同发明人)
  本书是适合关心安全的开发人员和安全从业人员阅读的一本优秀入门书。本书写得非常好,容易阅读,讲述的内容正是您所需要的。”
                     ——David Wagner(加利福尼亚大学伯克利分校副教授)
  “软件开发人员是代码安全的第一道也是最佳的一道防线。本书为他们提供安全开发知识和相关的工具,以便在软件成为最终产品使用之前消除安全漏洞。”
                     ——Howard A. Schmidt(前白宫计算机安全顾问)

图书特色

图书前言

跟随太阳的指引,我们告别了旧世界。
  —克里斯托夫·哥伦布

  我们生活在一个经济空前增长的时代,而计算机和通信技术则不断地推动着这种增长。我们使用软件实现工厂自动化、贸易现代化,并将信息传递到那些依赖信息的人手中。我们生活在信息时代,而软件是使信息为我们所用的主要手段。
  没有足够的安全性,我们将无法充分发挥数字时代的潜力。但令人奇怪的是,许多打着计算机安全旗号进行的活动事实上根本就不是在解决安全问题,而是清理安全问题产生的混乱局面而已。病毒扫描程序、防火墙、补丁管理以及入侵检测系统,是我们弥补软件安全不足所采用的所有手段。而软件行业将更多的精力放在了对安全缺陷的修补上,而不是致力于一开始就创建安全的软件。这并不是说我们认为这些缺陷修补的机制没有价值。就如同每艘海轮上都应有救生艇,对于我们软件行业来说,能建立一种快速修补最新发现漏洞的机制,这既是有益的、也是健全的。但是,即使这样,软件的安全状态仍然堪忧。每天都会发现新的漏洞。在某种意义上,我们成了盼望着每次轮船出海的时候都需要使用救生艇了。
  要想改变软件安全的这种状态,就要改变软件构建的方式。这并不是件容易的事情。毕竟,程序员会犯无数错误!虽说潜在的错误可能会是无限的,但实际上,程序编写整体上却倾向于重复相同的错误。缓冲区溢出漏洞存在了大约20年,这一事实就是此论点很好的例证。1998年,莫里斯(Morris)病毒使得Internet编程团体注意到缓冲区溢出会导致对安全性的破坏,但是,直到2004年,缓冲区溢出仍然被国际漏洞公布组织(Common Vulnerabilities and Exposures,CVE)列为引发安全问题的头号诱因[CWE,2006]。这种熟知错误的大量重复提示我们:当前遇到的许多安全问题是可预防的,而软件团体拥有避免这些错误出现所必需的经验技巧。
  21世纪初,我们激动地投身到软件构建之中,这使人联想到拓荒年代投身造船事业的情景。哥伦布到达美洲的时候,拓荒是经济扩张背后的驱动力,而轮船则是拓荒者周游世界的工具。在哥伦布的年代,成为经济强国需要成为一个海军强国,这是因为,在轮船能够安全航行于新的贸易航线之后,才能使发现一块新大陆带来价值。同样,要使信息技术能带来好处,人们所使用的计算机系统就必须是安全的。一些批评家对即将到来的“网络战役”发出了警告,但是,既然我们知道软件安全作为一种主要因素左右着愿意投身网络技术的信任人群的数量,那么,我们就不会害怕像这种电子毁灭的预言。
  我们认为,确保自己的作品是安全的,这是软件构建人员的责任。软件安全问题不能留给系统管理员或最终用户去处理。网络安全、明智的管理员以及谨慎的使用都很重要,但是,从长远来看,如果软件天生就有漏洞,这些努力最终是徒劳的。尽管有时候安全看起来会像是一种黑色艺术,或者是一种碰运气的事情,但是,我们希望证实不是这么回事。把安全说得让人感觉是不可能的或者是神秘的,这就有点言过其实了。有了正确的知识和正确的工具,通过将安全构建到软件开发过程中,软件安全是可以实现的。
  我们经常会遇到这样一些程序员,他们质疑软件安全是否是一种有价值的目标。毕竟,如果昨天没有人攻击你的软件,你为什么要相信明天就会有人攻击呢?安全要求付出某些额外的思考、更多的注意力和更大的努力。在过去的数10年间,这些额外的工作并不显得那么太重要,而那些没有经历过安全问题的程序员则用他们的好运气来判断未来,从而忽视了安全性。在对“挑战者”号航天飞机失事原因的调查中,Richard Feynman发现,NASA的风险评估是基于以前的航天飞机发射都是成功的这一事实得出的[Feynman,1986]。他们知道过去已经出现过不正常的运行状态,但他们用还没有发生过灾难来作为理由,从而相信永远都不会发生灾难。由此导致的安全系数的削弱使得失事的发生几乎是不可避免的。Feynman写到:“当玩俄罗斯轮盘赌的时候,第一枪安全逃过并不能在面对下一枪时用于自我安慰。”
  安全编程:使用静态分析
  有两条交织的主线贯穿于全书:软件安全和静态源代码分析。我们将广泛讨论引起安全问题的常见代码错误,对每一种错误的安全后果进行解释,并对安全路线的制定给出建议。我们最常见的建议最终将归结到本书的主题:在代码错误被利用之前,使用静态分析工具识别出这些代码错误。我们主要关注商业软件,这些软件既可用于企业商用,也可用于普通消费者,但我们的重点将放在商用系统上。我们不会陷于那些构建有特殊安全需求的软件所必需的细节。尽管在构建一个操作系统或者一个电子投票机的特殊安全需求方面,需要注意的方面很多,但是,在我们遇到的程序员中,更多的人需要了解如何构建一个安全的网站或者如何构建一个安全的企业应用程序。
  此外,我们首先希望提供一些实用的、并且立即就可以实行的建议,以消除软件安全缺陷。我们用了许多存在漏洞的实际代码示例来演示我们所讨论的安全缺陷,在本书随赠的光盘中还有一套静态源代码分析工具,这样,读者可以使用我们讲过的检测技术来进行实验。
  本书不是一本安全功能特性、安全框架、或者安全API使用的指导书。我们不讨论Java安全管理器(Java Security Manager),不讨论密码技术,也不讨论身份管理的正确方法。无疑,这些都是重要的话题。这些内容太重要了,实际上,都有专门的书来探讨这些话题。而我们的目标是关注那些与安全功能特性无关的东西,一旦它们出错,将会致软件于危险的境地。
  多数情况下,恶魔隐藏于细节之中。安全法则(以及违反安全法则)必须映射到其在源代码中的表现。我们将重点放在用C语言和Java语言编写的程序上,因为这两者是当前我们最常遇到的编程语言。我们还将大量关注其他语言。现在很多安全敏感的项目都是用C#、Visual Basic、PHP、Perl、Python、Ruby以及COBOL完成的,但是,即使是蜻蜓点水,在一本书里写到所有的语言也是很困难的。
  某些情况下,我们所讨论的许多问题都是与编程语言无关的,我们希望读者在阅读这些示例的时候,能够越过示例的语法,理解其在你所使用的编程语言上的衍生结果。
  读者对象
  本书为那些已经下决心优先考虑软件安全的人而写。我们希望程序员、项目经理以及软件架构师都能从阅读本书之中获益。尽管我们的宗旨并非关注有关软件安全和静态分析的详细知识,但本书涵盖了足够深入的这类主题内容,我们希望专业的代码审查人员和渗透测试人员也能够从中获益。我们假设读者能够轻松使用C语言或者Java语言编写程序,而且阅读用这两种语言写的简短示例都不会太吃力。某些章节倾向于更多地使用其中的某一种语言。例如,在关于缓冲区溢出的章节中,示例是用C语言编写的。
  本书的组织结构
  本书分为4个部分。第一部分“软件安全和静态分析”,讲述了一些概述性的内容:软件安全问题、静态分析帮助改善软件安全性的方法、以及将静态分析集成为软件开发过程的一部分的观点。第二部分“常见问题”,我们将关注一些普遍存在的安全问题,无论软件的功能是什么,都会受这些问题的影响。而在第三部分“特性与特色”中,我们将着手处理影响常见的各种程序以及特殊的软件功能的安全相关问题。第四部分“静态分析实践”,我们给出一组展现静态分析如何能够改进软件安全的实际动手练习,这些练习将第一部分、第二部分和第三部分的知识融会起来。
  第1章,“软件安全问题”。该章从程序员的视角勾画出软件安全的困境:为什么软件总是容易出问题?为什么用来捕获程序Bug的典型方法用在查找安全问题上就不那么灵了?
  第2章,“静态分析简介”。该章讨论静态分析所能解决的各种问题,包括结构、质量,当然,还有安全问题。我们将对一些开源的和商业的静态分析工具进行一个快速的概览。
  第3章,“作为代码审查过程组成部分的静态分析”。该章将探讨静态分析工具如何能作为安全审查过程的组成部分付诸实施。我们分析,软件开发组织的决心是这些工具能得到有效使用的基础。此外,我们还将讨论基于静态分析输出的度量标准。
  第4章,“静态分析技术内幕”。该章将深入探讨静态分析工具是如何工作的。我们将探究构建一套静态分析工具相关的基础组件,并考虑静态分析工具在实现良好的精确度和仍然能够扩展到对数百万行代码进行分析这两者之间的平衡。
  第二部分对软件中普遍存在的安全问题进行了概述。整个这部分的章节及后续的章节中,我们将对安全的编程给出积极的指导,并随后使用专门的代码示例(其中许多代码来自实际的程序)来演示要避免出现的缺陷。顺着这种思路,我们将指出静态分析能够对软件安全提供帮助的地方。
  第5章,“输入的处理”。该章讨论程序员曾面对的最头痛的软件安全话题,这同时也是未来他们最可能要面对的问题:对大量输入窗体以及非信任输入衍生的数据进行处理。
  第6章,“缓冲区溢出”和第7章,“缓冲区溢出伴随的问题”。这两章将讨论一个输入带来的软件安全问题,这个问题已经伴随了我们数十年,即缓冲区溢出。第6章以一种战术性的方法开始:如何找出最有可能引起可被利用的缓冲区溢出的特殊代码结构部分。第7章将探究缓冲区溢出的间接原因,例如整数回绕(wrap-around)。然后,我们将进一步展开并对缓冲区溢出及解决这一问题的可能方法进行一种更为战略性的研究。
  第8章,“错误和异常”。该章主要探讨特殊情况下程序员考虑问题的方法。尽管错误和异常是相当少见的引发安全漏洞的直接原因,但却以一种非直接的方法与漏洞相关。意外条件和安全问题之间有着紧密的联系,因此,错误处理和恢复将是一个永远的话题。最后,该章还将讨论常见的日志记录和程序调试方法,这些通常都是作为一个整体与错误处理联系在一起的。
  第三部分采用一样的风格进行积极的指导并给出专门的代码示例,以解决在常见类型的程序中发现的、以及和某些特殊软件功能特性相关的涉及安全的问题。
  第9章,“Web应用程序”。该章将探讨当前最流行的安全话题:万维网。我们将探讨Web和HTTP协议所特有的安全问题。
  第10章,“XML与Web服务”。该章将研究一个日渐显现的安全挑战:使用XML和Web服务在分布式组件之外构建应用程序。
  尽管安全功能并不是我们所关注的焦点,但某些安全功能有明显的错误倾向,因而应当对其特殊对待。第11章,“隐私与秘密”,该章将对一些程序进行探讨,这些程序需要对私有信息提供保护,或者,更为常见的情况下,需要保存秘密。第12章,“具有特权的程序”,该章将探讨一些特殊的安全需求,当编写的程序需要操作与调用该程序的用户不同的权限集时,必须考虑这些安全需求。
  第四部分是有关获得静态分析体验的内容。本书的随赠光盘中包含了一个静态分析工具,这是我们公司—Fortify Software公司免费赠送的版本,光盘中还有许多示例工程的源代码。
  第13章,“Java语言源代码分析练习”,是从Java语言角度出发的一个涵盖静态分析的实验指导。第14章,“C语言源代码分析练习”的内容和第13章一样,只不过其中的例子和练习是用C语言编写的。
  本书使用的一些约定
  讨论安全错误会使人陷入一种消极的心态,或者抱有一种悲观的态度。我们力图通过将注意力放在纠正安全问题所需要做的事情上,从而坚持积极的立场。详细说明很重要,所以,当我们讨论编程错误的时候,我们试图给出一个有指导意义的实例来演示某种编程错误在详细审查之下的情形。当针对一个特殊问题的解决方案与我们的原始实例相比较发生较大变化的时候,我们也会给出一份纠正这个问题后重写的代码版本。为直截了当地标示这些例子,我们用这个图标表示在给出的代码中故意包含了一个缺点,用这个图标表示给出的代码中
  已经纠正了那个缺点。
  致谢
  我们的编辑—Addison-Wesley出版社的Jessica Goldstein为我们做的事情远远不止帮我们熟悉出版流程;在RSA 2005上和她的一番谈话使得这个项目得以启动。Addison-Wesley出版社的其他员工也为我们提供了巨大的帮助(并且非常耐心),他们中包括:Kristin Weinberger、Chris Zahn、Romny French以及Karen Gettman。
  第1、2、3章的部分内容源于我们过去几年中写的一些技术论文和杂志上发表的文章。我们要感谢这些论文和文章的共同执笔人:Gary McGraw、Yekaterina Tsipenyuk O誑eil、Pravir Chandra以及John Steven。
对于一些实在是粗糙又粗糙的草稿,我们的审稿人真是受苦了,而他们总是返回一些有建设性的反馈意见。要多多感谢Gary McGraw、David Wagner、Geoff Morrison、Gary Hardy、Sean Fay、Richard Bejtlich、James Walden、Gang Cheng、Fredrick Lee、Steve Riley和Hao Chen。我们也受到了来自Fortify公司技术咨询部的很多必要的鼓励,他们有:Gary McGraw、Marcus Ranum、Avi Rubin、Fred Schneider、Matt Bishop、Li Gong、David Wagner、Greg Morrisett、Bill Pugh以及Bill Joy。
  Fortify公司的每一个人都大力支持我们的工作,他们的大量工作都体现在了本书的随赠光盘上。我们非常感激他们给予我们的这些支持。我们还应当大力感谢Greg Nelson,他修正了我们对于静态分析的一些观点。
  我们要特别感谢我们的家人:Brian家的Sally和Simon以及Jacob家的Jonathan。和在硅谷软件公司工作的人住在一起需要有巨大的耐心,而同时要容忍他写软件和写书那简直是圣人都比不过了。最后,还要感谢我们的父母。你们给我们指引了这条路,我们不打算转投他处。

封底文字

创建安全的代码,仅有好的意图是远远不够的。程序员要知道:他们的代码几乎需要在各种使用环境和各种配置之下都是安全的。静态源代码分析为用户提供了使用优秀的工具来审查其工作的能力,从而找出各类可直接导致安全漏洞的错误。现在,本书提供了一份关于静态分析的完整指导:如何进行静态分析,如何将其集成到软件开发过程以及如何在代码安全审查期间最大化其功效等。 静态分析专家Brian Chess和Jacob West探讨了当前最为常见的安全缺陷类型。他们使用来自实际安全事件的Java和C代码实例阐明了:如何发现编码错误,如何防止出现编码错误以及如何通过静态分析来快速找出类似的错误。本书读者对象是所有关注构建更加安全的软件的人:软件开发人员、软件安全工程师、软件分析师以及软件测试人员。 本书内容包括: ■ 为什么常规的Bug捕获技术经常找不出安全问题。 ■ 怎样才能通过静态分析帮助程序员做好安全工作。 ■ 决定一个静态分析工具成败的关键属性和算法。 ■ 提高代码静态分析效率的36种技术。 ■ 70多种严重安全漏洞及其详细解决方案。 ■ 来自FireFox、OpenSSH、MySpace、eTrade、Apache httpd以及其他 ■ 更多软件的漏洞实例。 ■ 处理非可信输入的技术。 ■ 消除缓冲区溢出的战术和战略方法。 ■ 避免出现Web应用程序、Web 服务以及Ajax相关的错误。 ■ 关注安全的日志技术、调试技术以及错误/异常处理技术。 ■ 秘密和机密信息的创建、维护和共享。 ■ 带你穿越静态分析的详尽过程。 “为了能够对Java进行静态分析,我们对其进行了相关设计。本书向您展示了如何应用高级静态分析技术来创建更为安全、更为可靠的软件。” ——Bill Joy(Sun Microsystems公司的共同创始人、 Java语言的共同发明人) 本书是适合关心安全的开发人员和安全从业人员阅读的一本优秀入门书。本书写得非常好,容易阅读,讲述的内容正是您所需要的。” ——David Wagner(加利福尼亚大学伯克利分校副教授) “软件开发人员是代码安全的第一道也是最佳的一道防线。本书为他们提供安全开发知识和相关的工具,以便在软件成为最终产品使用之前消除安全漏洞。” ——Howard A. Schmidt(前白宫计算机安全顾问)

图书序言

使用静态分析工具进行软件安全审查和代码审查
  建筑工程师在开课的第一天往往会学习关键的一课:“关注并弄清楚桥梁修建细节,否则你建起来的桥就有可能坍塌”。这一课还通过播放Tacoma Narrows大桥把自己晃塌(http://www.enm.bris.ac.uk/anm/tacoma/tacoma.html)的一段视频非常有力地进行了例证。图1展示了1940年这座大桥600英尺的一段坍塌落入水中的情景。与此相反,在软件工程课程的第一天,那些初入门的开发人员得到的教导却是他们能构建所有能想到的东西。通常他们都是从“hello world”开始的。
  图1  Tacoma Narrows大桥600英尺的一段坍塌落入普吉特湾(Puget Sound),
  就像这座桥自己扭曲转动到坍塌一样。建筑工程师们早期就得到这方面的
  警告:如果他们不能苦练为一个优秀的工程师的话,就会发生这样的事故
  过度乐观的软件开发方式无疑已导致创建了很多难以想像的东西,然而,从安全的视角来看,这同样也让我们自己陷入了困境。简单地说,我们没能想到:如果发生有目的的恶意攻击,我们的软件会出现什么情况?
  许多当前的软件是非常脆弱的,只有当其环境是纯净而可预知的时候,其功能才能正常运转。如果将我们这脆弱的软件所运行的环境换作一种好斗的、恶意的环境(就像Internet这样的实际环境),软件的崩溃将非常地惊人,它将轰然落入类似的普吉特湾。
  当今计算机安全中存在的最大问题就是大多数系统在构建的时候就没有安全意识。诸如防火墙之类的反应式网络技术能帮我们减轻“脚本小子们”对服务器的攻击,但这类技术并不能解决真正的安全问题:质量低劣的软件。如果我们想要解决这类计算机安全问题,就需要在构建安全的软件上下更多的功夫。
  软件安全是使得软件能够在恶意攻击的情况下安全而正常运转的一种软件构建实践。本书主要讲解的就是关于软件安全中最重要的实践之一:使用静态分析工具进行代码审查。
  随着业界人士对软件安全的重要性愈来愈重视,人们逐步采纳并开展了一系列的最佳实践来致力于解决这一问题。微软公司的可信赖计算计划(Trustworthy Computing Initiative)取得了显著的成就。许多Cigital公司的用户正处于企业范围的软件安全计划之中。当前,在实践中应用的绝大多数方法都是围绕着对开发人员、测试人员以及架构师进行培训,软件工件的分析和审计,开展安全工程。将软件安全尽可能深入地引进到开发过程,并利用软件从业人员过去几年中学过的这些安全工程课程,舍此无它。
  在我的《Software Security》那本书中,我引入了一组称作“接触点(touchpoint)”的7大最佳实践。实现软件安全要求对大多数组织的软件构建方式进行某些更改。好在这些更改并不是基础性的、地震式的或者是开销巨大的更改。事实上,采用一系列简单明了的最佳工程实践,将安全交叉插入到现有开发过程并以此方式开展软件设计,所要做的更改通常就只是这些。
  图2详细说明了这些软件安全接触点(touchpoint),并展示了软件从业人员如何将这些接触点应用到软件开发过程中产生的各种软件工件。这意味着理解如何将安全工程引入到需求、架构、设计、编码、测试、检验、度量和维护等过程中。
图2  在《Software Security: Building Security In》一书中引入和充实的软件安全接触点
  某些接触点本身就比其他接触点影响力要大。首先采用这些最具影响力的接触点不失为一种稳健的做法。排在前面的两个接触点是使用静态分析工具进行代码评审和对架构的风险分析。本书全部内容将围绕前者展开。
  所有的软件工程都至少会产生一个工件:代码。这一事实使得我们将代码审查放在我们列表中第一号的位置。在代码级别上,我们的关注点将集中在发现缺陷上,特别是那些用来扫描代码中常见漏洞的静态分析工具所能找出来的缺陷。现在,有好几家工具厂商都致力于这一领域,其中包括Fortify Software公司—Brian和Jacob就供职于此。
  发现缺陷(Bug)不仅数量众多,而且也很常见(就像维吉尼亚乡村的臭虫一样),其中包括了由于使用或误用存在漏洞的API(如C语言中的gets()、strcpy()等)而带来的一些很难处理的东西—例如臭名昭著的缓冲区溢出。无论是人工的还是(甚至更为重要的)使用静态分析工具的自动化方法,代码审查总是试图在软件发布之前识别出安全缺陷。
  当然,哪种单一的技术都不是万能药。对于实现安全的软件来说,代码审查是一项必要而非充分的例行工作。安全缺陷(尤其是C语言和C++语言中的安全缺陷)是一种实际存在的问题,而架构的缺陷则是一个大问题。开展代码审查是一项极其有用的活动,但是,就算是这样,这种审查只能识别缺陷。最好的情况下,代码审查能揭示出50%左右的安全问题。而架构的问题很难(并且很大程度上不可能)通过紧盯代码的方式找出来。对于由无数代码行组成的现代系统来说,更是这样。而一种综合的软件安全方式包括了对代码审查和架构分析的全面整合运用。
  就其本质来讲,代码审查要求编码方面的知识。在代码审查期间,一个几乎没有软件编写和编译经验的信息安全从业者没有太大用处。代码审查步骤最好还是交给开发组织的成员来完成,尤其是当他们配备了某种现代源代码分析工具的时候,更应该让他们进行这项工作。除了那些在编程语言和代码级漏洞解决方案方面具有丰富经验的信息安全人员以外,代码审查阶段的工作本质上并不适合网络安全专家来做。对于那些目前正在尝试通过信息安全部门在企业实行软件安全的组织来说,可能会对这种说法非常惊讶。即使这些组织关于安全性实施的这种想法是严谨的,但是,只有满足代码审查对在编码方面有具体的实践经验这一需求的时候,安全性才能在代码级别上成功实施。
  如何查找缺陷?或者,找到缺陷后该怎么办?大多数开发人员对于这些问题都没有什么概念,这是个问题。这正是本书的切入点。你手上的这本书,是关于安全性静态分析和代码审查的所有已出版著作中水平最高的一部。本书不仅会告诉你缺陷是什么(我有时候称之为软件安全的“缺陷检阅”方法),还将教你如何使用现代静态分析工具来找出这些缺陷,此外,更为重要的是,本书还教你如何来改正这些缺陷。通过将书中的教导付诸实践,你将在解决软件安全问题的道路上迈出一大步。

  Gary McGraw博士
  于维吉尼亚州贝利维尔(Berryville,Virginia)
  2007年3月6日

  公司:www.cigital.com
  播客(Podcast):www.cigital.com/silverbullet
  博客(Blog):www.cigital.com/justiceleague
  图书著作:www.swsec.com

作者简介

Brian Chess;Jacob West:Brian Chess: Brian Chess 是Fortify Software公司的创始人和首席科学家,他的研究重点是用于创建安全系统的实用方法。他在圣克鲁兹的加州大学(University of California)获得计算机工程博士学位,在那里他研究在代码中查找安全相关缺陷问题的静态分析。
Jacob West: Jacob West 管理Fortify Software公司的安全研究小组。该小组负责将安全知识构建到Fortify Software公司的产品中。他提出了各种编程语言、框架和风格的专家意见,同时还研究有关现实中的系统为何会失效的问题。

译者简介

董启雄 韩平 程永敬:暂无简介

译者序

在我以前工作过的一个团队中,在解决软件质量和安全性问题的“摸着石头过河”的过程中,我们从理论上知道,除了继续在做的二进制代码的所谓“黑盒”测试外,还应该尝试开展“白盒测试”。于是,有一个小组引入了一位“白盒”测试工程师。在我的印象中,那位工程师整日在看代码,屏幕上总是很多代码在翻翻滚滚;他采用人工的方式遍历代码,以期找出问题。
  过了没有多久,大概也就是我基本上熟悉这位工程师的时候,突然有一段时间看不到他了。问起他们的小组负责人,才知道已经辞职了。原因双方都有,我记得比较清楚的是老板不知道他做了些什么,或者说,工作成绩看不到,工作效果不明显。我们首次进行代码静态分析的尝试就这样失败了。
  翻译本书的过程中,我实际上是带着对静态分析的怀疑和疑问的:代码分析可能有效吗?究竟能提供多大的帮助呢?代码分析人员和程序员怎么沟通呢?等等。毕竟,曾经的尝试给我留下了比较深的负面印象。
  采用自动化方式进行代码静态分析,是本书介绍的静态分析技术和方法的核心,其应用目标重点放在了代码安全问题的查找上。读了这本书,我对代码静态分析有了新的认识。这确实是关于代码静态分析的一本很好的入门书!尽管本书的重点放在了针对安全问题的代码静态分析上,但是,书中讲的基本原理也适用于一般的代码静态分析。读了这本书,我想,我们的尝试之所以失败,除了其他的各种主客观因素外,至少在技术思路上有两个问题:一是采用人工的方式,效率很低,很难让静态分析的效果快速、量化显现出来;二是在结果的表达上,缺少像Fortify的Audit Workbench给出来的那样一份详尽而易懂的报告。就像书中所说,结果的表示和审计非常重要!
  编写安全代码的重要性我们已经一再阐述,相信读者也已经认同。我们之前已经为大家推荐了程序员角度的《编写安全的代码》和安全测试人员角度的《软件安全测试艺术》,这次,我们为大家推荐这本书。这本书是面向开发人员和安全测试人员的一种较高级别的书。说它较高级别,是因为静态分析在实践上要求的起点比较高,熟练使用静态分析工具开展安全测试,尽管同样需要安全方面的知识,但还需要更多的关于软件开发方面的知识。比如,读者应该了解编译原理,知道基本的数理逻辑方面的概念,还应当有基本的编程语言方面的知识等。所以说,作为“白盒”测试的一种方式,静态分析对安全测试人员提出了较高的要求,甚至可能需要开发团队的人员来参与这项工作。
  不过,好在有这本书,它从基础讲起,让我们快速地建立起静态分析技术的基本概念,并从实践的角度了解静态分析工具如何用于我们的安全测试中,特别是能够理解结果应该如何表达,如何使用。通过本书,相信大家能全面地了解静态分析技术和静态分析工具,并为进一步实际开展静态分析工作打下基础。
  本书的翻译工作由程永敬组织,主要由董启雄、韩平、程永敬负责翻译,参加翻译的还有高晓玲、李波、张宝玲、叶伟、卢敏、汪顶武、安志琦、费玮、张旭等。
  由于时间有限,加之译者的精力和能力所限,尽管我们尽了自己最大努力,但书中仍会有不少不尽人意之处,敬请读者不吝指正!您可以发送邮件到:  chengyongjing@126.com。

  程永敬
  2007年11月

图书目录

译者序

前言
作者简介
第一部分 软件安全和静态分析
第1章  软件安全问题 1
1.1  仅有防御性编程还不够 1
1.2  安全功能≠安全的功能 3
1.3  质量的误区 4
1.4  软件开发全局中的静态分析 6
1.5  漏洞分类 7
1.5.1  7种有害的领域 9
1.5.2  “7种有害的领域”与“OWASP
前10名” 11
1.6  小结 11
第2章  静态分析简介 12
2.1  静态分析的能力和局限性 12
2.2  通过静态分析解决问题 13
2.2.1  类型检查 14
2.2.2  风格检查 15
2.2.3  程序理解 16
2.2.4  程序验证和属性检查 17
2.2.5  Bug查找 19
2.2.6  安全审查 20
2.3  一点理论,一点实际 21
2.3.1  成功准则 22
2.3.2  分析源代码与分析编译后的代码 25
2.4  小结 28
第3章  作为代码审查过程组成部分的
静态分析 29
3.1  执行代码审查 29
3.1.1  代码审查周期 30
3.1.2  避开可利用性陷阱 33
3.2  将安全审查加入到现有的开发过程中 34
3.2.1  采用工具的疑虑 36
3.2.2  小处着手,循序渐进 38
3.3  静态分析度量标准 39
3.4  小结 44
第4章  静态分析技术内幕 45
4.1  建模 45
4.1.1  词法分析 46
4.1.2  解析 46
4.1.3  抽象语法 47
4.1.4  语义分析 48
4.1.5  跟踪控制流 49
4.1.6  跟踪数据流 51
4.1.7  污染传播 52
4.1.8  指针别名歧义 52
4.2  分析算法 53
4.2.1  断言检查 53
4.2.2  单纯本地分析 54
4.2.3  本地分析方法 57
4.2.4  全局分析 58
4.2.5  研究性的工具 60
4.3  规则 62
4.3.1  规则格式 62
4.3.2  用于污染传播的规则 65
4.3.3  本书中讨论的规则 67
4.4  报告结果 67
4.4.1  结果的分组和分类 69
4.4.2  消除非预期的结果 69
4.4.3  解释结果的意义 70
4.5  小结 73
第二部分 常 见 问 题
第5章  处理输入 75
5.1  验证内容 76
5.1.1  验证所有输入 77
5.1.2  验证各种来源的输入 77
5.1.3  建立可信边界 83
5.2  如何进行验证 85
5.2.1  使用强输入验证 85
5.2.2  避免黑名单法 89
5.2.3  不要混淆可用性和安全性 91
5.2.4  拒绝不良数据 92
5.2.5  默认执行正确的输入验证 93
5.2.6  检验输入的长度 100
5.2.7  限制数值输入 102
5.3  防止元字符攻击 104
5.3.1  使用参数化请求 105
5.3.2  路径操纵 108
5.3.3  命令注入 109
5.3.4  日志欺骗 110
5.4  小结 112
第6章  缓冲区溢出 113
6.1  缓冲区溢出简介 113
6.1.1  利用缓冲区溢出漏洞 114
6.1.2  缓冲区分配策略 116
6.1.3  跟踪缓冲区大小 120
6.2  字符串 122
6.2.1  天生危险的函数 122
6.2.2  有界字符串操作 127
6.2.3  有界函数的常见缺陷 132
6.2.4  保留Null终止符 138
6.2.5  字符集、表达式和编码 141
6.2.6  格式串 145
6.2.7  更完善的字符串类和类库 148
6.3  小结 151
第7章  缓冲区溢出伴随的问题 152
7.1  整数 152
7.1.1  回绕错误 153
7.1.2  截断和符号位扩展 154
7.1.3  有符号数和无符号数之间的转换 156
7.1.4  检测和防止整数溢出的方法 157
7.2  运行时保护 162
7.2.1  更安全的编程语言 162
7.2.2  更安全的C语言 164
7.2.3  动态缓冲区溢出保护 166
7.2.4  动态保护基准结果 169
7.3  小结 170
第8章  错误和异常 171
8.1  利用返回代码处理错误 171
8.1.1  检查C语言中的返回值 172
8.1.2  检查Java中的返回值 173
8.2  管理异常 174
8.2.1  捕获顶层的任何东西 175
8.2.2  消失的异常 176
8.2.3  只捕获需要处理的异常 177
8.2.4  控制已检测的异常 178
8.3  防止资源泄露 180
8.3.1  C和C++ 180
8.3.2  Java 183
8.4  日志记录和调试 185
8.4.1  集中日志记录 185
8.4.2  在最终代码中不包含调试帮助和
“后门”访问代码 187
8.4.3  清除备份文件 189
8.4.4  不要容忍“复活节彩蛋” 190
8.5  小结 190
第三部分 特性与特色
第9章  Web应用程序 191
9.1  用于Web的输入和输出验证 192
9.1.1  预料到浏览器已遭到破坏 192
9.1.2  认为浏览器是一种一览无余的事物 194
9.1.3  保护浏览器免受恶意内容的攻击 195
9.2  HTTP考虑 205
9.2.1  使用POST,而不是GET 205
9.2.2  请求顺序 207
9.2.3  错误处理 208
9.2.4  请求出处 210
9.3  维护会话状态 211
9.3.1  使用强用户会话标识符 212
9.3.2  强制会话空闲超时和最大会话
持续时间 213
9.3.3  在认证的基础上开始一个新的
会话 215
9.4  为输入验证使用Struts架构 216
9.4.1  建立Struts Validator 217
9.4.2  对所有操作使用Struts Validator 218
9.4.3  验证每一个参数 220
9.4.4  维护验证逻辑 221
9.5  小结 223
第10章  XML与Web服务 224
10.1  使用XML 224
10.1.1  使用一个标准兼容的XML语法
分析程序 225
10.1.2  开启验证 226
10.1.3  要小心外部引用 229
10.1.4  保持对文档查询的控制 232
10.2  使用Web服务 235
10.2.1  输入验证 235
10.2.2  WSDL苦恼 236
10.2.3  过度暴露 237
10.2.4  过去错误的新机会 238
10.2.5  JavaScript劫持:一种新的边界 238
10.3  小结 242
第11章  隐私与秘密 243
11.1  隐私与规则 243
11.1.1  识别私有信息 243
11.1.2  处理私有信息 245
11.2  外发密码 249
11.2.1  源代码中不能有密码 249
11.2.2  不存储明文密码 251
11.3  随机数 255
11.3.1  在Java中生成随机数 255
11.3.2  在C和C++中生成随机数 257
11.4  密码技术 261
11.4.1  选择一个好的算法 261
11.4.2  不要自以为是 262
11.5  内存中的秘密 264
11.5.1  使保持秘密的时间最短 265
11.5.2  保守地共享秘密 266
11.5.3  安全地删除秘密 267
11.5.4  防止不必要地复制秘密 268
11.6  小结 269
第12章  具有特权的程序 270
12.1  特权的含义 271
12.1.1  最小特权原理 271
12.1.2  这次我是认真的:不相信
每一件事 273
12.2  管理特权 274
12.2.1  在实践中应用最小特权 274
12.2.2  限制文件系统上的特权 277
12.2.3  谨防非期待的事件 279
12.3  特权提升攻击 281
12.3.1  文件访问竞态条件 282
12.3.2  不安全的临时文件 287
12.3.3  命令注入 289
12.3.4  标准文件描述符 290
12.4  小结 291
第四部分 静态分析实践
第13章  Java语言源代码分析练习 293
练习13.0  安装 293
练习13.1  留意结果,现在开始 294
练习13.2  人工审计源代码 300
练习13.3  运行Fortify SCA 302
练习13.4  理解原始的分析结果 303
练习13.5  分析一个完整的应用程序 307
练习13.6  使用Audit Workbench调整结果 308
练习13.7  审计一个问题 310
练习13.8  执行一个完整的审计 313
练习13.9  编写自定义规则 316
练习13.2中问题的答案 321
第14章  C语言源代码分析练习 324
练习14.0  安装 325
练习14.1  留意结果,现在开始 325
练习14.2  人工审计源代码 330
练习14.3  运行Fortify SCA 331
练习14.4  理解原始的分析结果 332
练习14.5  分析一个完整的应用程序 335
练习14.6  使用Audit Workbench调整结果 335
练习14.7  审计一个问题 338
练习14.8  执行一个完整的审计 341
练习14.9  编写自定义规则 342
练习14.2中的问题答案 346
结束语 349
参考文献 351

教学资源推荐
作者: 王卫红 江颉 董天阳 等编著
作者: 主编 宫云战 参编 赵瑞莲,张威,王雅文,张俞炜
作者: [英]伊恩·萨默维尔(Ian Sommerville) 著
参考读物推荐
作者: [美] 马特·魏斯费尔德(Matt Weisfeld)著
作者: 李龙 黎连业 编著
作者: Lawrence J.Peters
作者: (以)Daniel Galin