公开性

在自由软件中,在纯内部讨论和公开联系声明之间通常有一个相对平滑的连接。这部分因为目标读者一直不明:因为大多数文章都是公开可访问的,项目无法控制整个世界对此的印象。某人—假设是slashdot.org的一个编辑—可能为谋篇文章带来几百万的读者,而本来没人认为它会被项目之外的人看到。这就是开源项目生活的世界,但是在实践中,这种风险通常很小。通常情况下,项目希望公开化的声明就会得到最大的公开化,只要你能用正确的机制指出其对外部世界的新闻价值。

对于主要的声明,通常会有4或5个主要分发渠道,所有的声明最好尽可能同时发出:

  1. 你的项目主页可能是项目中被看得最多的页面。如果你确实有主声明,请在此放一个夸张的广告。这个广告一定是一个简短的概要,可以链接到有更多信息的新闻稿。

  2. 同一时间,你的站点一定也要有一个“新闻”或“新闻发布”区,可以详细写明声明。新闻稿的部分目的是提供一个单独的权威“声明对象”,这样别的站点可以用来链接,所以要以此为依据确保其结构:要么每个发布一个网页,或每个是一个博客条目,要么其他种类可以被链接的实体,同时与同一区域的其他新闻稿区分开来。

  3. 如果你的项目有RSS供稿(见the section called “RSS供稿”),请确保声明也会出现在这里。这也可能在你创建新闻稿时自动发生,取决于你是如何设置的站点。

  4. 如果声明是软件的新版本,请更新http://freshmeat.net/中的项目条目(关于首次创建条目请看the section called “通告”)。每当你更新Freshmeat条目时,该条目就会出现在Freshmeat当日的变更列表中。这个变更列表不仅仅会在Freshmeat本身更新,也会出现在许多被很多人关注的门户站点(包括http://slashdot.org)上。Freshmeat也会通过供稿提供相同的数据,所以即使那些没有订阅你的项目供稿的人,也会通过Freshmeat看到声明。

  5. 向你的项目声明邮件列表发送一个邮件。这个列表的名称应当是“announce”,例如announce@yourprojectdomain.org,因为现在这已经成为了标准的习惯,而且列表的管理者一定要说明该列表的内容很少,仅用于主要的项目声明。大多数此类声明都是关于软件的新版本,但是偶尔也会其他事件,例如本章后面说的募集资金激励,发现安全漏洞(见the section called “声明安全漏洞”),或者项目方向的重大转移,也会发布到这里。因为内容很少,只用于重大事件,所以announce列表通常是项目中订阅最多的列表(当然,这意味着你不要滥用它—发布之前一定要小心)。为了防止其他人,甚至是垃圾邮件发出声明,announce列表应该一直需要审核。

要力争在所有的三个地方同时作出声明,越接近越好。人们在邮件列表中看到声明,而在主页或新闻发布区上没有对应的内容时就会感到困惑。如果你能将各方面的(邮件、网页等等)修改排队,并依次发出,你可以将这种时间差控制到最小。

对于不太重要的事件,你可以省略上面的某个发布出口。根据事件的重要程度,该事件还是会被外部世界注意到。例如,软件的一个新版本是主要事件,而设定下一次发布的日期,即使有些新闻价值,也不会比发布本身更重要。设定日期值得我们在日常邮件列表(而不是声明列表)中发一个邮件,以及更新项目时间线或网页状态,但仅此而已。

然而,你还是会在网上的其他地方的讨论中看到日期。在你的列表中的潜伏者仅仅会听,而不会说任何事,并不一定在其他地方也是沉默的。口碑会造成广泛的传播;你必须考虑到这一点,使用这种方式构建更小的声明,鼓励信息传递的精确性。特别的,你期望引用文章一定要在明确的在引用部分出现,就像你在写正式的新闻稿。例如:

仅仅是进度更新:我们计划在2005年8月中旬发布Scanley的2.0版本。你可以检查http://www.scanley.org/status.html的更新。新特性是正则表达式搜索。

其他特性包括: ...也会包含其他bug修正,包括 ...

第一段很简短,仅提供了最重要的信息(发布日期和主要新特性),以及访问进一步新闻的URL。如果某人的屏幕仅出现这个段落,也完成的足够好了。邮件的余下部分可以省略,不会损失内容的要点。当然,有时人们会链接整个邮件,但是更常见的,他们只会引用一小部分。假设后一种的可能性,你所做的也让他们的工作更容易,此外也因为所引用的内容获得了更多的影响力。

声明安全漏洞

安全漏洞的处理与其他类型bug报告有所不同。在自由软件中,公开透明的工作方式通常几乎是宗教信条。只要你愿意,标准bug处理过程的每个步骤都是可见的:最初到来的报告,实现确认的讨论以及最终的修正。

安全bug则有些不同。它们会危及用户数据,甚至是用户的整个电脑。如果公开讨论这个问题,就是将其公示天下—包括那些会恶意利用这个bug的人。甚至仅仅是有效率的提交一个修正宣布bug的存在(会有潜在的攻击者看到公开项目的提交日志,有系统的查找变更,以便在以前的代码中获取安全问题)。大多数开源项目都为公开性和秘密性的冲突准备了相同的处理步骤,基于如下的基本指导方针:

  1. 在发现修正之前,不要公开谈论bug;然后在宣布bug的同时立刻提供修正。

  2. 尽可能迅速的完成修正—特别是如果项目外的某人报告了这个bug,因此你知道至少有一个项目外的人能够破解这个漏洞时。

在实践中,那些原理会导致一系列标准化的步骤,将会在下面的小节描述。

接收报告

很明显,人们需要从任何人那里接收安全报告的能力。但是不能用常规的bug报告地址,因为那样所有人都会看到。因此,可以设定一个接收安全bug报告的邮件列表。这个邮件列表一定不要有公共可读的归档,而且必须严格控制其订阅权—只有长期可信的开发者可以在列表上。如果你需要为“可信的”作出正式的定义,可以规定为“所有提交过两年及以上的人”,或类似的,避免偏袒。这将会是处理安全bug的团队。

理想状态下,安全列表不应该是垃圾保护的或需要经过审核的,因为你不会希望仅仅因为在周末没有审核者而造成重要的报告被过滤掉或者被延迟。如果你使用自动垃圾邮件保护软件,可以尝试使用较高的容忍设置;允许部分垃圾邮件通过总比漏掉一个报告要好。当然,为了列表的效率,你应当将列表的地址广而告之;但是因为它没有审核,或者只有轻微的防垃圾设置,一定要确保要有邮件地址隐藏的变化,就像Chapter 3, 技术基础设施the section called “归档中的地址隐藏”所说的。幸运的是,地址隐藏不需要将地址变的难以识别;举个例子,可以看http://subversion.tigris.org/security.html,以及该网页的HTML源代码。

默默的开发修正

当接收到报告时,在安全列表上要怎么做?首要任务是评估问题的严重性和紧急性。

  1. 漏洞很严重吗?它会造成使用该软件的计算机被恶意攻击接管吗?或者说,是否仅仅会泄漏他们文件大小的信息吗?

  2. 破解这个漏洞很简单吗?攻击可以脚本化,还是需要环境相关的知识、有意识的猜测甚至运气?

  3. 向你报告了这个问题?当然,这个问题的答案不会改变漏洞的本性,但你可以以此判断有多少人了解此事。如果报告来自于项目自己的开发者,你可以松一口气了(也就一口),因为你可以相信他们不会告诉别人。另一方面,如果是来自类似anonymous14@globalhackerz.net的邮件,你最好立即行动。尽管这个好人提醒了你,但你无法知晓她告诉了多少人,或者她还会等多少时间去破解正式安装系统中的这个漏洞。

请注意,我们这里讨论的范围仅仅是紧急极端 紧急之间。即使报告来自于一个已知的、友好的来源,网上的其他人也可能早就发现了这个bug,只是没有报告。唯一不紧急的情况是,bug在本性上不会严重的影响安全。

另外,“anonymous14@globalhackerz.net”的例子并不可笑。你可能真的会从隐形身份的人那里得到bug报告,根据他们的词汇和行为,你无法判断他们是否站在你一边。这没有关系:如果他们向你报告了安全漏洞,他们会觉得理应得到好的回报,你应当友好的回应。感谢他们的报告,给他们一个发布修正的时间或截止时间,并与他们保持联系。有时,他们会给一个日期—那是将在该日期公布bug的威胁的暗示,无论当时你是否已经准备妥当。这看起来像是一种权利的欺凌游戏,但是更像是一种预先的免疫行动,因为之前有对许多令人失望的迟钝的软件制造者,没有将安全报告认真对待。无论如何,你不能对他视而不见,毕竟,如果bug很严重,他拥有的知识会给你带来很大的麻烦。友好的对待这种报告者,希望他们也能投桃报李。

另一个安全bug的常见报告者是安全专家,一些长期审核代码并钻研软件漏洞的人。这些人通常精通两个领域—他们不仅会接收,也会发送报告,可能比你项目的大多数开发者都多。他们也通常会为修正某个漏洞设定公布于众的截止日期。截止日期也许可以讨价还价,但是这取决于报告者;截止日期已经成为安全专家唯一认可可靠方法,可以让组织迅速的定位安全问题。所以,不要认为截止日期很野蛮,这是久经考验的传统,这样做有足够的理由。

当你知道了严重性和紧急性,你就可以开始修正了。有时,需要在优雅和速度之间做出权衡;这也是为什么在开始前要首先确认紧急性。当然,也要保证讨论仅限于安全列表用户,原始的报告者(如果她希望加入),以及所有因技术原因必须参与的人之间。

不要提交修正到版本库。在公开之前,请一直用补丁的形式。如果你准备提交,即使采用了无辜的日志信息,也会让某些人注意到并理解此变更。你永远无法知道谁在关注你的版本库,以及他们感兴趣的原因。关闭提交邮件可能会有些用;但是毕竟提交邮件序列本身会让人起疑,而且数据已经进入了版本库。只应该以补丁的形式完成所有的开发,并保持补丁在私密的地方,也可以是一个单独的独立版本库,只有知晓此bug的人能够知道。 (如果你使用分布式的版本控制系统,例如Arch或SVK,你可以在完全版本控制下完成这个工作,只需要保证外来者无法访问此版本库。)

CAN/CVE号码

你或许看到过随安全问题出现的CAN号码CVE号码。例如看起来类似“CAN-2004-0397”或“CVE-2002-0092”。

两种号码都代表了相同类型的实体:在http://cve.mitre.org/上维护的“常见漏洞和曝光”列表中的一个条目。这个列表的目的为所有已知的安全问题提供标准化的名称,这样每个人都可以在讨论时使用唯一的标准化的名称,并提供一个可以查找更多信息的中心地点。 “CAN”和“CVE”的唯一区别是前者代表了候选条目,还未经CVE编辑委员会认可,而后者则是经过认可的条目。 然后,两种类型的条目都对公众可见,条目的编号不会随着认可而改变—仅仅是“CAN”前缀替换成了“CVE”。

CAN/CVE条目本身并不包含bug的完整描述,以及如何防范的信息。相反,它只会包含一个简短的摘要,然后是到参考和外部资源的列表(例如邮件列表归档),人们可以去查看详细信息。http://cve.mitre.org/的真正目的是提供一个组织良好的空间,每个漏洞都可以有一个名称以及获取更多信息的途径。一个条目的例子可以看http://cve.mitre.org/cgi-bin/cvename.cgi?name=2002-0092。请注意,引用可以非常的简洁,其中的来源表现为神秘的缩写。这些缩写的关键点可以看http://cve.mitre.org/data/refs/refkey.html

如果你的漏洞达到了CVE的标准,你或许会希望得到一个CAN号码。这个过程是故意封闭的:一般来说,你需要认识某人,或认识某人认识某人。这并不是表面上的那么疯狂。为了避免被伪造的或编写糟糕的提交压垮,CVE编辑委员会只从已知和信任的来源获取提交。然而,为了获取你的漏洞列表,你需要从你的项目找一个CVE编辑委员会认识的人。在你的开发者中询问一下是否认识某人之前曾经完成过CAN过程,或知道某人会认识。这样做的好处是该链路上的某处,某人会知道足够的信息告诉你 a) 根据MITRE的标准,它不会作为漏洞或曝光,所以没有提交的意义,或者 b) 这个漏洞已经有了CAN或CVE号码。后者可能是因为该bug已经在另一个安全忠告列表上发布了,例如位于http://www.cert.org/或者位于http://www.securityfocus.com/的BugTraq邮件列表。 (如果是在你的项目对此一无所知的情况下发生了这种情况,你一定会担心还有什么不知道的。)

如果你已经得到了CAN/CVE号码,你一定希望尽早将其纳入bug研究中来,这样以后的所有交流都可以引用这个号码。在公布之前,CAN条目会被禁止访问;这个条目会作为占位符保持(这样就不会丢失名称),但不会揭示任何漏洞信息,直到你宣布此bug并修正了它。

关于CAN/CVE流程的更多信息可以查看http://cve.mitre.org/about/candidates.html,一个开源项目中使用CAN/CVE号码的例子可以看http://www.debian.org/security/cve-compatibility

预通知

一旦你的安全响应团队(那些在安全邮件列表上的开发者,或者那些你认为应该加入到解决特定报告的人)准备好了修正,你就要决定如何描述它。

如果仅仅是提交你们的修正到版本库,或者是向全世界宣布,所有使用该软件的人就必须立刻升级,否则就要经受被攻击的风险。有时,更应该对某些特别重要的用户进行预提醒。对于客户端/服务器软件这一点尤其重要,因为也许某些用户的服务器是攻击的诱人目标。那些服务器的管理员也许会对提前一两天进行升级而感到感激,这样他们就可以在破解出现在公众之前做好保护。

预提醒的意思是在公布之前向那些管理员发送邮件,告诉他们这些漏洞以及如何修正。一定要确保只向你相信会保守秘密的人发送预提醒。也就是,接收预提醒的资格包括两重意思:接收者一定是在运营一个大的,重要的服务器,影响重大,而且这些接收者也一定不会在公开之前到处乱说这个安全问题。

向每个接收者单独(每次一个)发送预提醒邮件。不要一次向整个列表的接收者发送,因为他们会看到其他人的名字—那样意味着告诉了每个接收者他们的服务器有安全漏洞。完全通过暗送(BCC)也不是好方法,因为某些管理员使用垃圾过滤会屏蔽或减少BCC邮件的等级,因为现在有太多使用BCC发送的垃圾邮件。

以下是一个预提醒邮件:

From: 你的名字
To: admin@large-famous-server.com
Reply-to: 你的名字(不要用安全列表地址)
Subject: 重要Scanley漏洞提醒。


这个邮件是Scanley服务器安全警告的重要预提醒。

不要向任何人转发本邮件。公共声明将会在3月19日发布,我们很希望在此
之前能够保密此信息。

您收到此邮件是因为(我们认为)您运行了Scanley服务器,并希望在19号公
布此安全漏洞之前做好补丁。
参考:
===========

   CAN-2004-1771: Scanley查询堆栈溢出漏洞:
==============

   如果服务器的locale设置配置错误,而且客户端发送了不合法的查询,会导
   致可以运行任何命令。

严重程度:
=========

   非常严重,可以导致服务器上任意代码的执行。

周边工作:
============

   在scanley.conf中将'natural-language-processing'选项设置为'off',可以关闭
   这个漏洞。

补丁:
======

   以下补丁适应于Scanley 3.0、3.1和3.2。

   一个新的公共版本(Scanley 3.2.1)将会在3月19日发布,同时该漏洞也会
   公开。你可以现在打补丁,或者等待公开版本。3.2与3.2.1的唯一区别将是此
   补丁。

[...补丁在这里...]

如果你有CAN号码,即使该信息依然是保密的,它的MITRE页面没有任何内容,也请在预提醒中提供(上面例子中显示的)。包含CAN号码允许接收者可以知晓自己被预提醒的bug正是他们将来可能通过公共渠道获知的bug,这样他们就不必为是否要采取进一步的行动而感到担心,关键点就是CAN/CVE号码。

公开分发修正

处理安全bug的最后一步是公开分发修订。在一个单独的完整的声明中,你需要描述该问题,如果有CAN/CVE号码,也要提供,描述工作的背景,以及如何永久修正。通常情况下,“修正”意味着将软件升级到新版本,有时也可能是应用一个补丁,特别是如果你的软件以源代码形式运行时。如果你要发布新版本,一定要确保是与现有的某个版本的区别就是安全补丁。使用此方法,保守的管理员就可以作出升级,无需担心会影响其他的功能;他们也不必担心将来的升级,因为安全补丁将会理所当然的出现在未来版本中。(关于发布的详细信息可以看Chapter 7, 打包、发布和日常开发the section called “安全发布”。)

无论公开修正是否包含了新的版本,不要像发布新版本那样粗糙:在项目声明列表中发送一封邮件,发布一个新的新闻稿,更新Freshmeat条目等等。你不应该因为项目的名誉,而试图减弱安全bug的存在性,你应当确立与安全声明问题的严重程度相匹配的基调和突出程度。如果安全漏洞仅仅是轻微的信息暴露,而不会导致用户攻克整个计算机,无需大惊小怪。你甚至会觉得无需为此分散声明列表的注意力。毕竟,如果项目每次都喊狼来了,用户会误以为软件很不安全,而且会在真的有大问题要宣布时不相信你。关于判断严重性的更好的介绍可以看http://cve.mitre.org/about/terminology.html

一般情况下,如果你对如何处理安全问题并不确定,可以找某个更有经验的人讨论一下。评估和处理漏洞更像是一种学习得到的技巧,一开始很容易误入歧途。