C和C++安全编码(原书第2版)
上QQ阅读APP看书,第一时间看更新

前言

1988年11月爆发的Morris蠕虫事件造成当时全球10%的互联网系统陷入瘫痪,作为对该事件的回应,当月美国国防部高级研究计划局(Defense Advanced Research Projects Agency,DARPA)成立了CERT。CERT位于宾夕法尼亚州匹兹堡市的软件工程研究院(Software Engineering Institute,SEI)内,这是一个由美国国防部发起的研发中心,并受联邦政府资助。

CERT最初的工作重点是对各种网络事件做出快速响应和分析。这里所说的事件既包括得逞的攻击(如系统受损与拒绝服务等),也包括未得逞的攻击企图、探测和扫描。自1988年以来,CERT共已接到逾22665个报告计算机安全事件或咨询有关信息的热线电话,已处理逾319992起计算机安全事件,而且每年报告的事件数目呈持续增长的态势。

虽然对事件做出及时响应必不可少,但是这还不足以保护互联网和互联的信息系统的安全。分析表明,大部分计算机安全事件是由特洛伊木马、社会工程学(social engineering)以及软件漏洞利用(exploitation)造成的,包括软件缺陷、设计决策、配置决策以及非预期的系统间交互等。CERT监控漏洞信息的公共来源并且经常性地收到漏洞报告。自1995年以来,CERT已经收到超过16726份漏洞报告。每收到一份报告,CERT就会分析报告所述的可能的漏洞,并与软件制造者协作,通知其产品中存在安全缺陷,促进并追踪其对问题的响应 [1]

和事件报告相似,漏洞报告也以惊人的速度持续增长 [2]。虽然对漏洞的管理抑制了这一进程的发展,但是对于解决互联网和信息系统的安全问题来说,这同样远远不够。为了解决日益增加的漏洞和事件问题,必须采取相应的措施:在源头有效地控制它们,即必须在软件的开发阶段和随后的维护工作中避免引入软件漏洞。对现有漏洞的分析表明,大部分漏洞都是由少数根本原因导致。本书旨在传授开发者有关这些根本原因的知识,并介绍避免引入漏洞的措施。

本书读者对象

对任何采用C和C++开发或维护软件的人来说,本书都是非常有价值的。

·如果你是一位C/C++程序员,本书将教你如何识。别会导致软件漏洞的常见编程错误,理解这些错误是如何被利用的,并以安全的方式实现解决方案。

·如果你是一位软件项目经理,本书将教你识别软件漏洞的风险及导致的后果,对投资开发安全软件给出指导。

·如果你是一位计算机专业的学生,本书将教你有用的编程实践,帮助你避免不良的开发习惯,使你能够在职业生涯中开发出安全的程序。

·如果你是一位安全分析师,本书对常见的漏洞提供了细致的描述,并提供了检测漏洞的方法和实用的规避措施。

本书组织和内容

本书提供了C和C++编程中关于安全实践方面的实用指导。安全的程序需要安全的设计,然而,如果开发者不了解C和C++编程中许多固有的安全陷阱,那么即便是最佳设计也可能最终导致不安全的程序。本书对C和C++中常见的编程错误提供了详细的解释,并描述了这些错误是如何导致有漏洞的代码的。本书重点讨论C和C++编程语言以及相关库固有的安全问题,而不强调和外部系统(如数据库和Web服务器等)的交互中牵涉的安全问题。这些方面话题丰富,应单独讨论。希望本书对于涉及开发安全的C和C++程序的任何人都有所裨益,而不管具体开发何种应用。

本书围绕着软件工程师经常实现的、可能会导致安全问题的功能(例如,格式化输出和算术运算等)组织内容。每一章都描述了一些会导致漏洞的不安全编程实践和常见的错误、这些编程缺陷如何被利用、这种恶意利用所导致的后果,以及替代的安全做法等。对于软件漏洞的根源问题,例如,缓冲区溢出、整型范围错误和无效的格式字符串等,都有详细的解释。每一章都包含检测既有代码中漏洞的技术,以及如何安全地实现所需功能的措施。

本书包含以下各章。

·第1章:概述问题,介绍安全术语和概念,并对为何C和C++程序中存在如此多的漏洞发表看法。

·第2章:描述C和C++中的字符串操作、常见的安全缺陷以及由此导致的漏洞(包括缓冲区溢出攻击和栈溢出攻击),还介绍了代码注入(code injection)和弧注入(arc injection)两种漏洞利用方式。

·第3章:介绍任意内存写(arbitrary memory write)漏洞利用方式,它允许攻击者对内存中任意位置的一个地址进行写操作。该章描述这些漏洞利用方式如何用于在受害机器上执行任意的代码。由“任意内存写”导致的漏洞在稍后的章节中讨论。

·第4章:描述动态内存管理,讨论动态分配的缓冲区溢出、写入已释放内存,以及重复释放(double-free)漏洞。

·第5章:讨论整数安全问题(即与整数操作相关的安全主题),包括整数溢出、符号错误以及截断错误等。

·第6章:描述格式化输出函数的正确和错误的用法。对因这些函数的错误使用所导致的格式字符串和缓冲区溢出漏洞都有讨论。

·第7章:重点介绍并发和可能导致死锁、竞争条件和无效的内存访问序列的漏洞。

·第8章:描述和文件I/O相关的常见漏洞,包括竞争条件(race condition)和检查时间与使用时间(Time Of Check.Time Of Use.TOCTOU)漏洞。

·第9章:推荐一些可以整体改善C/C++应用程序安全性的具体开发实践。这些建议是对每一章中用于解决特定漏洞问题的推荐做法的补充。

本书包含数百个安全和不安全的代码示例以及漏洞利用示例。尽管其中有一些涉及与其他语言的比较,但是几乎所有例子都是用C和C++编写的。这些例子都在Windows和Linux操作系统上验证过。具体的示例程序通常已在一个或多个特定环境下编译和测试过,同时漏洞都被予以评估,以确定它们是否具体相关于以下因素,或者具有包含以下因素的普遍性:编译器版本、操作系统、微处理器、适用的C或C++标准、小端表示法(即低位在前、高位在后)或大端表示法(即高位在前、低位在后)架构,以及执行栈架构等。

本书以及基于它的在线课程,重点讨论通常导致软件漏洞的常见C和C++编程缺陷。尽管如此,限于篇幅,本书并未涵盖漏洞的每一个可能来源。与本书有关的附加与更新信息、活动时间表以及新闻参见www.cert.org/books/secure-coding/。书中讨论的漏洞也是参照来自US-CERT漏洞数据库(参见www.kb.cert.org/vuls/)的实际例子。

可以通过位于https://oli.cmu.edu/的卡内基·梅隆大学开放学习计划(Open Learning Initiative,OLI)。输入课程的密钥0321822137来访问与本书配套的安全编码在线课程。

[1] CERT与超过1900名软件、硬件开发者保持互动交流。
[2] 参见www.cert.org/stats/cert_stats.html以获得最新统计信息。