智者攻取勇士的城邑,倾覆他们所倚靠的保障。 | |
箴言 21:22 (NIV) |
本书描述了一系列在Linux和Unix系统上编写安全程序的指南。就本书而言,“安全程序”是指位于安全边界上的程序,它从不具有与该程序相同访问权限的源获取输入。这类程序包括用作远程数据查看器的应用程序、Web应用程序(包括CGI脚本)、网络服务器和setuid/setgid程序。本书不涉及修改操作系统内核本身,尽管此处讨论的许多原则确实适用。这些指南是通过调查从各种来源获得的关于如何创建此类程序的“经验教训”(以及作者的其他观察)而制定的,并将其重组为一系列更广泛的原则。本书包括针对多种语言的具体指导,包括C、C++、Java、Perl、PHP、Python、Tcl和Ada95。
您可以在http://www.dwheeler.com/secure-programs找到本书的主副本。本书也是Linux文档项目(LDP)的一部分,网址为http://www.tldp.org。它还在其他几个地方被镜像。请注意,这些镜像,包括LDP副本和/或您发行版中的副本,可能比主副本旧。我希望听到对本书的评论,但在发送评论之前,请先检查以确保您的评论对最新版本有效。
本书不涵盖保证措施、软件工程流程和质量保证方法,这些虽然重要但在其他地方已得到广泛讨论。这些措施包括测试、同行评审、配置管理和形式化方法。专门针对安全问题确定开发保证措施的文件包括通用准则(CC,[CC 1999])和系统安全工程能力成熟度模型[SSE-CMM 1999]。[Wheeler 1996]讨论了检查和其他同行评审技术。本书确实简要讨论了CC中的思想,但仅作为讨论安全要求的组织辅助手段。更通用的软件工程流程集在诸如软件工程研究所的软件能力成熟度模型(SW-CMM)[Paulk 1993a, 1993b]和ISO 12207 [ISO 12207]之类的文档中定义。质量系统的一般国际标准在ISO 9000和ISO 9001 [ISO 9000, 9001]中定义。
本书不讨论如何在给定环境中配置系统(或网络)以使其安全。这对于安全使用给定程序显然是必要的,但是许多其他文档讨论了安全配置。关于配置类Unix系统以使其安全的一本优秀的通用书籍是Garfinkel [1996]。其他关于保护类Unix系统的书籍包括Anonymous [1998]。您还可以在诸如http://www.unixtools.com/security.html之类的网站上找到有关配置类Unix系统的信息。有关配置Linux系统以使其安全的信息可在各种文档中找到,包括Fenzi [1999]、Seifried [1999]、Wreski [1998]、Swan [2001]和Anonymous [1999]。Geodsoft [2001]描述了如何强化OpenBSD,并且它的许多建议对于任何类Unix系统都很有用。[Mookhey 2002]讨论了关于审核现有类Unix系统的信息。对于Linux系统(以及最终的其他类Unix系统),您可能需要检查Bastille Hardening System,该系统试图“强化”或“收紧”Linux操作系统。您可以在http://www.bastille-linux.org上了解有关Bastille的更多信息;它在通用公共许可证(GPL)下免费提供。其他强化系统包括grsecurity。对于Windows 2000,您可能需要查看Cox [2000]。美国国家安全局(NSA)在http://nsa1.www.conxion.com维护了一套安全建议指南,包括“60分钟网络安全指南”。如果您尝试使用开源工具建立公钥基础设施(PKI),您可能需要查看Open Source PKI Book。有关防火墙和互联网安全的更多信息,请参见[Cheswick 1994]。
配置计算机只是安全管理的一部分,安全管理是一个更大的领域,还涵盖如何处理病毒、需要哪种组织安全策略、业务连续性计划等等。安全管理有国际标准和指南。ISO 13335是一份五部分的技术报告,提供了关于安全管理的指南[ISO 13335]。ISO/IEC 17799:2000定义了一套实践规范[ISO 17799];其声明的目的是为那些负责在其组织中发起、实施或维护安全的人员提供高级和通用的“信息安全管理建议”。该文档明确地将自身定义为“制定组织特定指南的起点”。它还指出,它包含的并非所有指南和控制措施都可能适用,并且可能需要未包含的其他控制措施。更重要的是,它们旨在成为涵盖多个领域的广泛指南,而不是旨在提供明确的细节或“操作指南”。值得注意的是,最初签署ISO/IEC 17799:2000时存在争议;比利时、加拿大、法国、德国、意大利、日本和美国投票反对其通过。但是,这些投票似乎主要是对议会程序的抗议,而不是对文件内容本身的抗议,当然,如果人们发现ISO 17799有帮助,他们可以随意使用它。有关ISO 17799的更多信息,请参见NIST的ISO/IEC 17799:2000 FAQ。ISO 17799与BS 7799第1部分和第2部分高度相关;有关BS 7799的更多信息,请参见http://www.xisec.com/faq.htm。ISO 17799目前正在修订中。重要的是要注意,这些标准(ISO 13335、ISO 17799或BS 7799第1部分和第2部分)均不旨在成为软件开发人员的详细技术指南;它们都旨在在多个领域提供广泛的指南。这一点很重要,因为仅仅遵循(例如)ISO 17799的软件开发人员通常不会生成安全的软件 - 开发人员需要的细节远比ISO 17799提供的要多得多。
位于http://www.caspr.org的通用接受安全实践与建议(CASPR)项目正试图将信息安全知识提炼成一系列供所有人使用的论文(根据GNU FDL许可证,以便未来的文档衍生品将继续供所有人使用)。显然,安全管理需要包括在发现和修复漏洞时及时应用补丁。Beattie [2002]提供了一个有趣的分析,分析了如何确定何时应用补丁,对比了错误补丁的风险与入侵风险(例如,在某些情况下,补丁在发布后10或30天应用是最佳的)。
如果您对漏洞的当前状态感兴趣,可以使用其他资源。http://cve.mitre.org上的CVE为每个(广泛传播的)漏洞提供了一个标准标识符。SecurityTracker Statistics 论文分析了漏洞,以确定最常见的漏洞是什么。http://isc.incidents.org/上的互联网风暴中心显示了世界各地各种互联网攻击的突出程度。
本书假设读者一般理解计算机安全问题、类Unix系统的通用安全模型、网络(特别是基于TCP/IP的网络)和C编程语言。本书确实包含有关Linux和Unix安全编程模型的一些信息。如果您需要更多关于基于TCP/IP的网络和协议如何工作的信息,包括其安全协议,请查阅关于TCP/IP的通用著作,例如[Murhammer 1998]。
当我最初开始编写本文档时,有很多短篇文章,但没有关于编写安全程序的书籍。现在还有另外两本关于编写安全程序的书。一本是John Viega和Gary McGraw的《构建安全软件》[Viega 2002];这是一本非常好的书,讨论了许多重要的安全问题,但它忽略了许多重要的安全问题,而这些问题在这里却被涵盖了。基本上,这本书选择了几个重要的主题并进行了很好的阐述,但代价是忽略了许多其他重要的主题。《Viega书》关于类Unix系统的信息比关于Windows系统的信息略多,但其中大部分与系统类型无关。另一本书是Michael Howard和David LeBlanc的《编写安全代码》[Howard 2002]。另一本书的标题具有误导性;这本书完全是关于为Windows编写安全程序的,如果您正在为任何其他系统编写程序,则基本上毫无价值。这不应该令人惊讶;它由微软出版社出版,其版权归微软所有。如果您正在尝试为微软的Windows系统编写安全程序,这是一本好书。另一个有用的安全编程指南来源是开放Web应用程序安全项目(OWASP)构建安全Web应用程序和Web服务指南;它更多地关注流程,而比本书的细节更少,但其中包含有用的材料。
本书涵盖了所有类Unix系统,包括Linux和各种Unix变体,并且特别强调Linux并提供关于Linux的具体细节。其中一些材料专门针对Windows CE,实际上,许多材料并不局限于特定的操作系统。如果您知道此处尚未包含的相关信息,请告诉我。
本书版权归(C) 1999-2002 David A. Wheeler所有,并受GNU自由文档许可证(GFDL)保护;有关更多信息,请参见附录C和附录D。
第2章讨论了Unix、Linux和安全的背景。第3章描述了通用的Unix和Linux安全模型,概述了进程、文件系统对象的安全属性和操作等等。接下来是本书的重点,即一套用于在Linux和Unix系统上开发应用程序的设计和实现指南。本书以第12章的结论结尾,随后是冗长的参考书目和附录。
设计和实现指南分为几类,我认为这些类别强调了程序员的观点。程序接受输入、处理数据、调用其他资源并产生输出,如图1-1所示;从概念上讲,所有安全指南都属于这些类别之一。我将“处理数据”细分为构建程序内部结构和方法、避免缓冲区溢出(在某些情况下也可以被视为输入问题)、特定于语言的信息和特殊主题。章节的顺序使材料更容易理解。因此,提供指南的章节讨论了验证所有输入(第5章)、避免缓冲区溢出(第6章)、构建程序内部结构和方法(第7章)、谨慎地调用其他资源(第8章)、明智地发送回信息(第9章)、特定于语言的信息(第10章),最后是关于特殊主题的信息,例如如何获取随机数(第11章)。