关于开源方法对安全性的影响,安全从业人员已经进行了很多辩论。其中一个关键问题是,开源将源代码暴露给所有人(包括攻击者和防御者)检查,而对于这种情况的最终影响,理性的人们意见不一。(注意 - 您可以通过访问本书的主要网站 http://www.dwheeler.com/secure-programs 获取本文的最新版本。)
首先,让我们考察一下安全专家怎么说。
布鲁斯·施奈尔 (Bruce Schneier) 是计算机安全和密码学领域的知名专家。他认为,聪明的工程师应该“要求任何与安全相关的东西都使用开源代码”[Schneier 1999],他还讨论了使开源软件安全必须满足的一些前提条件。高级加密标准 (AES) 加密算法的开发者文森特·里吉门 (Vincent Rijmen) 认为,Linux 的开源性质为更容易发现和修复安全漏洞提供了优越的途径,“不仅因为更多人可以查看它,更重要的是,因为这种模式迫使人们编写更清晰的代码,并遵守标准。这反过来又促进了安全审查”[Rijmen 2000]。
伊利亚斯·利维 (Elias Levy) (Aleph1) 是最受欢迎的安全讨论组之一 Bugtraq 的前任版主。在他的文章 “开源真的比闭源更安全吗?” 中,他讨论了使开源软件安全的一些问题。他的总结是:
那么,这一切是否意味着在安全漏洞方面,开源软件并不比闭源软件更好?不。开源软件当然有潜力比其闭源软件更安全。但请不要误解,仅仅是开源并不能保证安全。
惠特菲尔德·迪菲 (Whitfield Diffie) 是公钥密码学(所有互联网安全的基础)的共同发明人,也是 Sun Microsystems 的首席安全官和高级工程师。在他 2003 年的文章 风险业务:保守安全秘密 中,他认为专有供应商声称他们的软件因为是秘密的所以更安全的说法是无稽之谈。他识别并反驳了专有供应商提出的两个主要论点:(1)代码的发布对攻击者的好处大于对任何人的好处,因为许多怀有敌意的人也可以查看开源代码,以及(2)少数专家的眼睛胜过几个随机的眼睛。他首先指出,虽然让程序员访问一段软件并不能保证他们会仔细研究它,但有一群程序员可以被期望非常关心:那些亲自使用该软件或为依赖该软件的企业工作的人。“事实上,审计企业赖以保障自身安全的程序是企业自身信息安全组织的自然职能。” 然后他反驳了第二个论点,指出“至于开源对对手的用处大于对用户的优势的说法,这种论点与安全领域最重要的原则之一相悖:无法轻易更改的秘密应被视为漏洞。” 他最后指出
“在计算机软件中,依赖保密来保障安全简直是不现实的。您或许可以将程序的精确运作方式排除在公众流通之外,但您能阻止代码被认真的对手逆向工程吗?可能不能。”
约翰·维加 (John Viega) 的文章 “开源安全的迷思” 也讨论了相关问题,并总结如下:
开源软件项目可能比闭源软件项目更安全。然而,那些可以使开源程序更安全的东西——源代码的可用性,以及大量用户可以查找和修复安全漏洞的事实——也可能使人们产生虚假的安全感。
迈克尔·H·沃菲尔德 (Michael H. Warfield) 的“关于开源安全的思考” 对开源软件对安全性的影响持非常积极的态度。相比之下,弗雷德·施耐德 (Fred Schneider) 并不认为开源有助于安全性,他说“没有理由相信许多眼睛检查(开放)源代码会成功识别出允许系统安全受到损害的错误”,并声称“代码中的错误不是主要的攻击手段”[Schneider 2000]。他还声称开源排除了对构建过程的控制,但实际上存在这种控制——所有主要的开源程序都有一个或几个官方版本,这些版本都有“所有者”,他们的声誉岌岌可危。彼得·G·纽曼 (Peter G. Neumann) 讨论了“开放盒”软件(其中源代码可用,可能仅在某些条件下),他说“开放盒软件真的会提高系统安全性吗?我的回答是并非仅凭自身,尽管潜力巨大”[Neumann 2000]。TruSecure Corporation 在红帽(一家开源公司)的赞助下,撰写了一篇论文,阐述了他们为什么认为开源对于安全性更有效 [TruSecure 2001]。娜塔莉·沃克·惠特洛克 (Natalie Walker Whitlock) 的 IBM DeveloperWorks 文章 也讨论了利弊。布赖恩·威滕 (Brian Witten)、卡尔·兰德维尔 (Carl Landwehr) 和迈克尔·卡洛扬尼德斯 (Micahel Caloyannides) [Witten 2001] 在 IEEE Software 上发表了一篇文章,初步得出结论,源代码的可用性应该有利于系统安全;他们指出:
“我们可以从本次讨论中得出四个额外的结论。首先,访问源代码可以让用户提高系统安全性——如果他们有能力和资源这样做的话。其次,有限的测试表明,在某些情况下,开源生命周期产生的系统不太容易受到非恶意故障的影响。第三,对三个操作系统进行的调查表明,在一个 12 个月的时间段内,一个开源操作系统已知但未修补的漏洞的暴露程度低于两个专有操作系统中的任何一个。最后,只要不太安全的系统更有利可图,封闭和专有系统开发模式就会面临不鼓励部署和支持更安全系统的阻力。尽管有这些结论,但关于这个重要问题的论点仍处于形成阶段,并且迫切需要能够反映交付给客户的安全性的指标。”
斯科特·A·希萨姆 (Scott A. Hissam) 和丹尼尔·普拉科什 (Daniel Plakosh) 的 “开源软件中的信任和漏洞” 讨论了开源软件的优点和缺点。与其他论文一样,他们指出,仅仅因为软件是开放供审查的,并不一定意味着实际上已经执行了这种审查。实际上,他们指出这是所有软件(无论是开源还是闭源)的一个普遍问题——很多人是否会检查任何给定的软件都是值得怀疑的。一个有趣的观点是,他们证明了攻击者可以从对 OSS/FS 程序(Linux)进行的补丁中了解闭源程序(Windows)中的漏洞。在这个例子中,Linux 开发人员在攻击者试图攻击之前修复了一个漏洞,而攻击者正确地推测类似的问题可能仍然存在于 Windows 中(事实确实如此)。除非禁止 OSS/FS 程序,否则这种学习很难阻止。因此,OSS/FS 程序的存在可以揭示执行相同功能的 OSS/FS 和专有程序的漏洞——但在这个例子中,OSS/FS 程序首先被修复。
有人认为,没有源代码的系统更安全,因为由于攻击者可用的信息较少,攻击者应该更难找到漏洞。然而,这种论点有许多弱点,因为虽然源代码对于尝试为程序添加新功能非常重要,但攻击者通常不需要源代码来找到漏洞。
首先,区分“破坏性”行为和“建设性”行为很重要。在现实世界中,破坏一辆汽车比制造一辆汽车容易得多。在软件世界中,找到并利用漏洞比为该软件添加重要的新功能容易得多。由于这种差异,攻击者比防御者有许多优势。软件开发人员必须努力使他们的代码中任何地方都没有与安全相关的错误,而攻击者只需要找到一个。开发人员的主要报酬是让他们的程序工作……攻击者不需要让程序工作,他们只需要找到一个弱点。正如我稍后将描述的那样,攻击程序比修改程序需要更少的信息。
通常,攻击者(针对开源和闭源程序)首先了解程序具有的一般类型的安全问题。隐藏这些信息毫无意义;这些信息已经公开,而且在任何情况下,防御者都需要此类信息来保护自己。然后,攻击者使用技术来尝试查找这些问题;我将这些技术分为“动态”技术(您运行程序)和“静态”技术(您检查程序的代码——无论是源代码还是机器代码)。
在“动态”方法中,攻击者运行程序,向其发送数据(通常是有问题的数据),并查看程序的响应是否表明存在常见漏洞。开源和闭源程序在这里没有区别,因为攻击者没有查看代码。攻击者也可能会查看代码,即“静态”方法。对于开源软件,他们可能会查看源代码并搜索其中的模式。对于闭源软件,他们可能会搜索机器代码(通常以汇编语言格式呈现以简化任务)以查找基本相同的模式。他们还可能使用称为“反编译器”的工具,将机器代码转换回源代码,然后搜索源代码中的漏洞模式(就像他们搜索开源软件中的漏洞一样)。有关如何仍然可以检查闭源代码是否存在安全漏洞(例如,使用反汇编器)的讨论,请参见 Flake [2001]。这一点很重要:即使攻击者想使用源代码来查找漏洞,闭源程序也没有优势,因为攻击者可以使用反汇编器来重新创建产品的源代码。
非开发人员可能会问“如果反编译器可以从机器代码创建源代码,那么为什么开发人员说他们需要源代码而不是仅仅机器代码?” 问题是,虽然开发人员不需要源代码来查找安全问题,但开发人员确实需要源代码来对程序进行重大改进。虽然反编译器可以将机器代码转换回某种“源代码”,但生成的源代码非常难以修改。通常,大多数可理解的名称都丢失了,因此您会得到像“x123123”而不是像“grand_total”这样的变量,像“f123124”而不是像“display_warning”这样的方法,并且代码本身可能零星地散布着汇编代码。此外,_所有_注释和设计信息都丢失了。这对于查找安全问题来说不是一个严重的问题,因为通常您是在搜索指示漏洞的模式,而不是搜索内部变量或方法名称。因此,反编译器对于查找攻击程序的方法很有用,但对于更新程序没有帮助。
因此,开发人员在打算添加功能时会说“源代码至关重要”,但隐藏闭源程序的源代码并不能很好地保护程序。
有时有人指出,存在但未知的漏洞无法被利用,因此系统“实际上是安全的”。理论上这是正确的,但问题是一旦有人发现漏洞,发现者可能只会利用漏洞,而不是帮助修复它。拥有未知的漏洞并不能真正使漏洞消失;这仅仅意味着漏洞是一个定时炸弹,无法知道它们何时会被利用。从根本上说,有人利用他们发现的漏洞的问题对于开源和闭源系统都是一个问题。
有时会提出一个相关的说法(尽管与 OSS/FS 的直接关系不大),即人们不应该发布关于漏洞的警告并讨论它们。这在理论上听起来不错,但问题是攻击者已经通过大量渠道传播关于漏洞的信息。简而言之,这种方法会让防御者处于弱势,同时对阻止攻击者没有任何作用。过去,公司积极试图阻止漏洞的披露,但经验表明,总的来说,公司直到漏洞被他们的用户广泛知晓(然后用户可以坚持要求修复漏洞)才修复漏洞。这就是“完全披露”论证的一部分。Gartner Group 在 CNET.com 上一篇题为“评论:炒作才是真正的问题 - 科技新闻”的文章中发表了直率的评论。他们指出:
微软安全响应中心经理斯科特·库尔普 (Scott Culp) 的评论呼应了一场关于信息长期持续斗争中的常见说法。关于信息传播的道德讨论可以追溯到很久以前,而且非常熟悉。例如,几个世纪前,教会试图压制哥白尼和伽利略关于太阳是太阳系中心的理论……库尔普试图将微软产品最近出现的一连串漏洞归咎于“信息安全专业人员”,这充其量是虚伪的。也许,这也代表了一种试图转移对构建这些产品的公司的批评……各方的努力都有助于持续改进的过程。漏洞越广为人知,它们就越快得到修复。
有时有人认为,开源程序因为没有单个公司强制执行控制,所以允许人们插入特洛伊木马和其他恶意代码。特洛伊木马确实可以插入开源代码,但它们也可以插入专有代码。心怀不满或被贿赂的员工可以插入恶意代码,而在许多组织中,恶意代码比在开源程序中更难被发现。毕竟,组织外部的人员无法审查源代码,而且很少有公司进行内部代码审查(或者,即使他们这样做,也很少有人能确保审查过的代码实际上是使用的代码)。而且,闭源公司以后可能会被起诉的观点几乎没有证据;几乎所有的许可证都声明不承担任何保证,法院通常也不认为软件开发公司负有责任。
Borland 的 InterBase 服务器是一个有趣的案例。在 1992 年到 1994 年之间的某个时间,Borland 在他们的数据库服务器“InterBase”中插入了一个故意的“后门”。这个后门允许任何本地或远程用户操纵任何数据库对象并安装任意程序,在某些情况下甚至可以导致控制机器为“root”。这个漏洞在产品中至少存在了 6 年——没有人可以审查该产品,而且 Borland 也没有动力去消除这个漏洞。然后在 2000 年 7 月,Borland 发布了其源代码。“Firebird”项目开始使用源代码,并在 2000 年 12 月发现了 InterBase 的这个严重安全问题。到 2001 年 1 月,CERT 宣布了这个后门的存在,并发布了 CERT 咨询 CA-2001-01。令人沮丧的是,只需查看程序的 ASCII 转储(一种常见的黑客技巧)就可以轻松找到后门。一旦开源开发人员在审查代码时发现了这个问题,它就很快得到了修补。您可能会争辩说,通过保持密码未知,程序保持了安全,而打开源代码使程序变得不那么安全。我认为这是无稽之谈,因为 ASCII 转储很容易做到,并且是众所周知的标准攻击技术,而且并非所有攻击者都有突然宣布漏洞的冲动——事实上,无法确定这个漏洞是否已经被多次利用。很明显,在源代码公开后,源代码经过了长时间的审查,漏洞被发现并修复。描述这种情况的一种方法是说,原始代码是易受攻击的,当它第一次开源时,其漏洞变得更容易被利用,然后最终这些漏洞被修复。
拥有开放源代码的优势不仅扩展到正在被攻击的软件,还扩展到漏洞评估扫描器。漏洞评估扫描器有意查找已配置系统中的漏洞。最近的《Network Computing》评估发现,最好的扫描器(除其他外,它发现了最多的合法漏洞)是 Nessus,一个开源扫描器 [Forristal 2001]。
那么,底线是什么?我个人认为,当一个程序最初是闭源的,然后第一次开源时,它通常对任何用户来说都变得不太安全(通过暴露漏洞),并且随着时间的推移(比如几年),它有可能比闭源程序安全得多。如果程序最初是开源软件,那么公众的监督更有可能在其准备好被大量用户使用之前提高其安全性,但对这种说法有一些注意事项(这不是一个铁律)。仅仅使程序开源并不能突然使程序变得安全,仅仅因为程序是开源的并不能保证安全
首先,人们必须真正审查代码。这是辩论的关键点之一——人们真的会审查开源项目中的代码吗?各种因素都可能减少审查量:成为小众或很少使用的产品(潜在的审查者很少),开发人员很少,以及使用很少使用的计算机语言。显然,只有一个开发人员且没有任何其他贡献者的程序没有这种审查。另一方面,一个有一个主要作者和许多其他偶尔检查代码并做出贡献的人的程序表明,有人在审查代码(至少是为了做出贡献)。一般来说,审查者越多,有人识别出缺陷的可能性就越高——这是“多人之眼”理论的基础。请注意,例如,OpenBSD 项目不断检查程序的安全缺陷,因此其最内部组件肯定已经过长时间的审查。由于 OSS/FS 的讨论通常是公开进行的,因此潜在用户可以自行判断这种审查水平。
一个特别可能减少审查可能性的因素实际上不是开源。一些供应商喜欢将他们的“公开源代码”(也称为“源代码可用”)程序标榜为开源,但由于程序所有者拥有广泛的独家权利,其他人为所有者“免费”工作的动力会大大降低。即使是具有异常不对称权利的开源许可证(例如 MPL)也存在这个问题。毕竟,如果其他人将拥有他们不拥有的结果权利,人们就不太可能自愿参与(正如布鲁斯·佩伦斯 (Bruce Perens) 所说,“谁想成为别人的无薪雇员?”)。特别是,由于最有动力的审查者往往是试图修改程序的人,因此这种参与意愿的降低减少了“眼睛”的数量。伊利亚斯·利维 (Elias Levy) 在他关于开源安全性的文章中犯了这个错误;他被攻破的软件示例(例如,TIS 的 Gauntlet)在当时并不是开源的。
其次,至少一些开发和审查代码的人必须知道如何编写安全程序。希望本书的存在会有所帮助。显然,如果“多人之眼”中没有人知道要寻找什么,那也没关系。请注意,并非每个人都必须知道如何编写安全程序,只要那些知道如何编写安全程序的人正在检查代码更改即可。
第三,一旦发现这些问题,就需要快速修复并分发其修复程序。开源系统往往可以快速修复问题,但分发并不总是顺利。例如,OpenBSD 开发人员在审查代码以查找安全缺陷方面做得非常出色——但他们并不总是将已识别的问题报告回原始开发人员。因此,在一个系统中存在修复版本,但缺陷仍然存在于另一个系统中是完全有可能的。我相信这个问题随着时间的推移正在减少,因为没有人“下游”喜欢重复修复相同的问题。当然,确保安全补丁实际安装在最终用户系统上对于开源和闭源软件来说都是一个问题。
简而言之,开源软件对安全性的影响仍然是安全社区中的一个主要辩论,尽管许多著名的专家认为它具有更大的潜力变得更安全。