第 12 章 安全性

12.1. 为什么安全性如此重要

软件偶尔会引入错误。可以说,其中最危险的错误是那些导致安全漏洞的错误。从技术角度来看,应通过消除导致漏洞的错误来消除这些漏洞。然而,处理普通错误和安全漏洞的策略大不相同。

典型的轻微错误只会影响那些启用了导致错误的特定选项组合的用户。开发人员最终会发布一个补丁,然后发布一个没有错误的新软件版本,但大多数用户不会费心立即升级,因为他们从未遇到过这个错误。可能导致数据丢失的严重错误是一个更严重的问题。然而,谨慎的用户知道,除了软件错误之外,许多可能发生的意外都有可能导致数据丢失,因此他们会备份重要数据;此外,严重错误很快就会被发现。

安全漏洞则完全不同。首先,它可能在数年内不被发现,因为通常它不会导致软件故障。其次,恶意方可以使用它来获取对脆弱系统的未经授权的访问权限,破坏或修改敏感数据;在最坏的情况下,用户甚至不会注意到造成的损害。第三,暴露脆弱的系统通常会帮助攻击者入侵原本无法入侵的其他系统。因此,仅仅消除漏洞还不够:以最清晰和最全面的方式向受众通报漏洞,使他们能够评估危险并采取适当的措施。

12.2. 修复安全漏洞

在谈论端口和软件包时,安全漏洞可能最初出现在原始发行版或端口文件中。在第一种情况下,原始软件开发人员可能会立即发布补丁或新版本。请根据作者的修复及时更新端口。如果由于某种原因修复被延迟,请将端口标记为FORBIDDEN或在端口中引入补丁文件。如果端口存在漏洞,请尽快修复端口。在这两种情况下,请遵循提交更改的标准流程,除非您有权直接提交到端口树。

成为端口提交者并不意味着可以随意提交到任何端口。请记住,端口通常有维护者,必须得到尊重。

请确保一旦漏洞被修复,端口的版本号就会增加。这样,定期升级已安装软件包的用户就会看到他们需要进行更新。此外,一个新的软件包将被构建并通过 FTP 和 WWW 镜像分发,以替换有漏洞的软件包。除非在修复漏洞过程中DISTVERSION发生了变化,否则请增加PORTREVISION。也就是说,如果在端口中添加了补丁文件,则增加PORTREVISION,但如果将端口更新到最新的软件版本,并且已经修改了DISTVERSION,则不要增加PORTREVISION。请参考相关部分以获取更多信息。

12.3. 保持社区知情

12.3.1. VuXML 数据库

在发现安全漏洞后,尽快通知端口用户社区是一个非常重要和紧迫的步骤。这种通知有两个目的。首先,如果危险真的非常严重,那么采取即时解决方法是明智的。例如,在漏洞被修复之前,停止受影响的网络服务,甚至完全卸载端口。其次,许多用户往往只是偶尔升级已安装的软件包。他们会从通知中得知,一旦有修复后的版本可用,他们必须立即更新软件包。

考虑到端口树中存在大量端口,如果每次出现漏洞都发布安全公告,就会造成信息泛滥,当真正出现严重问题时,就会失去受众的关注。因此,在端口中发现的安全漏洞将记录在FreeBSD VuXML 数据库中。安全官团队成员也会监控它,以发现需要他们干预的问题。

提交者可以自行更新 VuXML 数据库,协助安全官团队,并将重要信息更快地传达给社区。那些不是提交者或发现了极其严重的漏洞的人,请不要犹豫直接联系安全官团队,如FreeBSD 安全信息页面所述。

VuXML 数据库是一个 XML 文档。它的源文件vuln.xml保存在端口security/vuxml内部。因此,文件的完整路径将为PORTSDIR/security/vuxml/vuln.xml。每次在端口中发现安全漏洞时,请在该文件中为其添加一个条目。在熟悉 VuXML 之前,最好的方法是找到一个适合当前情况的现有条目,然后将其复制并用作模板。

12.3.2. VuXML 简介

完整的 XML 格式非常复杂,超出了本书的范围。但是,要了解 VuXML 条目的结构,只需要了解标签的概念。XML 标签名称用尖括号括起来。每个开始标签<tag>必须有一个匹配的结束标签</tag>。标签可以嵌套。如果嵌套,内部标签必须在外部标签之前关闭。标签存在层次结构,即它们有更复杂的嵌套规则。这与 HTML 类似。主要区别在于 XML 是可扩展的,即基于定义自定义标签。由于其内在结构,XML 使原本无形的​​数据形成形状。VuXML 专门用于标记安全漏洞的描述。

现在考虑一个真实的 VuXML 条目

<vuln vid="f4bc80f4-da62-11d8-90ea-0004ac98a7b9"> (1)
  <topic>Several vulnerabilities found in Foo</topic> (2)
  <affects>
    <package>
      <name>foo</name> (3)
      <name>foo-devel</name>
      <name>ja-foo</name>
      <range><ge>1.6</ge><lt>1.9</lt></range> (4)
      <range><ge>2.*</ge><lt>2.4_1</lt></range>
      <range><eq>3.0b1</eq></range>
    </package>
    <package>
      <name>openfoo</name> (5)
      <range><lt>1.10_7</lt></range> (6)
      <range><ge>1.2,1</ge><lt>1.3_1,1</lt></range>
    </package>
  </affects>
  <description>
    <body xmlns="http://www.w3.org/1999/xhtml">
      <p>J. Random Hacker reports:</p> (7)
      <blockquote
        cite="http://j.r.hacker.com/advisories/1">
        <p>Several issues in the Foo software may be exploited
          via carefully crafted QUUX requests.  These requests will
          permit the injection of Bar code, mumble theft, and the
          readability of the Foo administrator account.</p>
      </blockquote>
    </body>
  </description>
  <references> (8)
    <freebsdsa>SA-10:75.foo</freebsdsa> (9)
    <freebsdpr>ports/987654</freebsdpr> (10)
    <cvename>CVE-2023-48795</cvename> (11)
    <certvu>740169</certvu> (12)
    <uscertta>SA10-99A</uscertta> (13)
    <mlist msgid="[email protected]">http://marc.theaimsgroup.com/?l=bugtraq&amp;m=203886607825605</mlist> (14)
    <url>http://j.r.hacker.com/advisories/1</url> (15)
  </references>
  <dates>
    <discovery>2010-05-25</discovery> (16)
    <entry>2010-07-13</entry> (17)
    <modified>2010-09-17</modified> (18)
  </dates>
</vuln>

标签名称应该是自解释的,因此我们只关注需要填写的字段

1这是 VuXML 条目的顶级标签。它有一个必填属性vid,用于指定此条目的全局唯一标识符 (UUID)(用引号括起来)。为每个新的 VuXML 条目生成一个 UUID(并且不要忘记将其替换为模板 UUID,除非从头开始编写条目)。使用uuidgen(1)生成 VuXML UUID。
2这是对发现问题的单行描述。
3受影响的软件包名称列在那里。可以给出多个名称,因为多个软件包可能基于单个主端口或软件产品。这可能包括稳定版和开发版分支、本地化版本以及具有不同重要构建时配置选项选择的从属端口。
4受影响的软件包版本列在那里,作为使用<lt><le><eq><ge><gt> 元素组合的一个或多个范围。请检查给定的版本范围是否重叠。
在范围规范中,*(星号)表示最小的版本号。特别是,2.* 小于 2.a。因此,可以使用星号表示范围以匹配所有可能的alphabetaRC 版本。例如,<ge>2.</ge><lt>3.</lt> 将选择性地匹配每个2.x 版本,而 <ge>2.0</ge><lt>3.0</lt> 不会,因为后者错过了 2.r3 并且匹配了 3.b
上面的示例指定受影响的版本为 1.6 及更高版本,但不包括 1.9,版本 2.x2.4_1 之前,以及版本 3.0b1
5多个相关的软件包组(本质上是端口)可以在<affected> 部分中列出。如果多个软件产品(例如 FooBar、FreeBar 和 OpenBar)从相同的代码库发展而来,并且仍然共享其错误和漏洞,则可以使用此方法。请注意,这与在单个 <package> 部分中列出多个名称的区别。
6版本范围必须允许使用PORTEPOCHPORTREVISION(如果适用)。请记住,根据排序规则,具有非零PORTEPOCH 的版本大于任何没有PORTEPOCH 的版本,例如,3.0,1 大于 3.1,甚至大于 8.9
7这是问题的摘要。此字段使用 XHTML。至少必须出现封闭的 <p></p>。可以使用更复杂的标记,但仅为了准确性和清晰度:请不要使用花哨的装饰。
8本节包含对相关文档的引用。鼓励尽可能多地提供引用。
9这是一个FreeBSD 安全公告
10这是一个FreeBSD 问题报告
11这是一个MITRE CVE 标识符。
12这是一个US-CERT 漏洞说明。
13这是一个US-CERT 技术网络安全警报。
14这是一个指向邮件列表中已存档帖子的 URL。属性 msgid 是可选的,可以指定帖子的消息 ID。
15这是一个通用 URL。如果其他引用类别都不适用,请使用它。
16这是问题公开的日期 (YYYY-MM-DD)。
17这是条目添加的日期 (YYYY-MM-DD)。
18这是条目中任何信息上次修改的日期 (YYYY-MM-DD)。新条目不能包含此字段。在编辑现有条目时添加它。

12.3.3. 测试对 VuXML 数据库的更改

此示例描述了软件包 dropbear 中漏洞的新条目,该漏洞已在 dropbear-2013.59 版本中修复。

作为先决条件,请安装security/vuxml 端口的最新版本。

首先,检查是否存在此漏洞的条目。如果有这样的条目,它将匹配软件包的先前版本 2013.58

% pkg audit dropbear-2013.58

如果未找到,请为该漏洞添加一个新条目。

% cd ${PORTSDIR}/security/vuxml
% make newentry

如果漏洞有一个MITRE CVE 标识符,可以使用以下命令:

% cd ${PORTSDIR}/security/vuxml
% make newentry CVE_ID=CVE-YYYY-XXXXX

其中 CVE-YYYYY-XXXX 是有效的 CVE 标识符。

如果漏洞是一个 FreeBSD 安全公告,可以使用以下命令:

% cd ${PORTSDIR}/security/vuxml
% make newentry SA_ID=FreeBSD-SA-YY-XXXXXX.asc

其中 FreeBSD-SA-YY-XXXXXX.asc 是已发布的FreeBSD 安全公告

验证其语法和格式

% make validate

前面的命令会生成vuln-flat.xml 文件。它也可以用以下命令生成:

% make vuln-flat.xml

至少需要安装以下软件包之一:textproc/libxml2textproc/jade

验证条目的 <affected> 部分是否会匹配正确的软件包

% pkg audit -f ${PORTSDIR}/security/vuxml/vuln-flat.xml dropbear-2013.58

确保该条目在输出中不会产生任何虚假匹配。

现在检查该条目是否匹配正确的软件包版本

% pkg audit -f ${PORTSDIR}/security/vuxml/vuln-flat.xml dropbear-2013.58 dropbear-2013.59
dropbear-2012.58 is vulnerable:
dropbear -- exposure of sensitive information, DoS
CVE: CVE-2013-4434
CVE: CVE-2013-4421
WWW: https://portaudit.FreeBSD.org/8c9b48d1-3715-11e3-a624-00262d8b701d.html

1 problem(s) in the installed packages found.

前一个版本匹配,而后一个版本不匹配。


上次修改日期:2024 年 3 月 9 日,由 Danilo G. Baio 修改。