FOSS运营轶事(202y)
2025-04-10 11:13:11 阿炯

本文上接《FOSS运营轶事(202x)》。

开源软件供应链安全问题 50 年

几十年来,软件复用是一个遥远的目标。现在,它变得非常真实。

1972 年 3 月,美国空军开始审查霍尼韦尔 Multics 系统,以了解它是否可以在安全环境中使用。该报告于 1974 年中期发布,结论是 Multics 虽然不安全,但优于其同类系统,可能是一个构建安全系统的合理起点。报告提出了在 “无害” 的系统调用中添加后门(当时称为 “陷阱门”)的潜在可能性。

当传递一个特定且极不可能的输入时,系统调用允许读取或写入内核内存的任意字。这个微小的变化将完全破坏系统的安全性,报告调查了这种变化可能如何被实施和隐藏的机制。

2024 年 3 月,安德烈斯・弗雷德(Andres Freund),一位在微软工作的 Postgres 开发者,注意到他的 Debian Linux 系统的 ssh 守护进程在处理互联网上常见的背景攻击流量时,CPU 占用率比平时高。经过进一步调查,弗雷德发现,Debian 系统上 ssh 链接的压缩库 liblzma 的最新版本中存在一个针对 ssh 的特定后门。现在,当传递一个特定且非常不可能的输入时,ssh 守护进程会允许互联网上的攻击者执行任意 shell 命令。这个微小的变化完全破坏了尖端 Debian 系统的安全性,在接下来的几周里,世界各地的安全研究人员都在调查这个变化是如何被做出并隐藏起来的。

由于 liblzma 是作为 xz 项目的一部分分发的,因此这次攻击现在被称为 xz 攻击

软件供应链安全问题在过去半个世纪中轮廓没有改变,因为它们是根本性的。在计算机安全领域没有简单的答案;软件供应链安全也不例外。我们能做的最好的事情就是不断提升我们的防御措施,而许多有希望的加强措施尚未得到普遍部署。本文旨在突出一些应该更广泛使用的有希望的方法,并指出需要更多工作的领域。我领导了 Go 编程语言和环境的开发工作超过十年,软件供应链安全是那个努力的一个具体焦点。本文基于那项工作,并从我的个人经验中汲取了一些例子,以及从整个软件行业汲取的例子。

探索问题

开源软件供应链安全是一个热门话题,尤其是在 xz 攻击之后,但究竟这意味着什么呢?在没有达成共识的定义的情况下,我建议以下这个包含三个部分的定义:

1.开源软件供应链攻击是指在交付前将恶意开源代码插入到可信软件中的行为。(借鉴了 Kim Zetter 的一个定义)

2.开源软件供应链漏洞是指由第三方开源组件引起的,在可信软件中存在的可利用的弱点。

3.开源软件供应链安全是针对开源软件供应链攻击和漏洞的防御工程。

这个定义有几个重要的细微差别。

首先,这里的硬件供应链并不在考虑范围内。例如,2013 年,《明镜》杂志报道,美国国家安全局(National Security Agency,简称 NSA)可以拦截针对目标的新计算机订单,并在其中安装后门软件或硬件组件。这种物理攻击超出了本讨论软件供应链的范围,尽管在某些情况下仍然值得考虑和防御。

第二个细微差别是,封闭源代码的软件组件并不引起关注。例如,在 2012 年,攻击者入侵了 Juniper Networks,并更改了 VPN(虚拟专用网络)的源代码,将随机数生成器中的一些关键常量进行了替换。结果是创建了一个后门,使得攻击者能够解密 Juniper 客户通过这些设备发送的所有 VPN 流量。这是一种软件供应链攻击,因为它在软件交付给 Juniper 客户之前就更改了软件。但它不是开源软件供应链攻击,因为恶意更改并未发生在 Jupiter VPN 所使用的开源组件之一。(随机数生成器最初之所以容易被后门攻击,多亏了 NSA 可能被认为是一次算法供应链攻击。)

作为一个例子,中国的开发者经常在中国国内的文件分享网站上寻找 Xcode 的副本,这些副本下载速度更快。2015 年,安全研究人员发现攻击者发布了一个修改过的 Xcode 副本,并努力使其成为 “Xcode 下载” 的中文搜索结果之首。这个版本,研究人员将其命名为 XcodeGhost,被恶意修改,向其构建的每个 iOS 应用中添加恶意代码。许多应用开发者下载并使用了它,注入的恶意软件至少进入了两个广泛使用的应用中。这是对分发机制的软件供应链攻击,而不是针对原始软件,但,同样,它并不是针对开源软件。

第三个细微差别在于,受影响的软件本身并不需要是开源的。例如,2021 年安全研究人员发现,开源的 Java 日志库 Log4j 在以特定格式记录文本时,会从任意 URL 下载并执行 Java 代码。Log4j 在 Java 生态系统中被广泛使用。以数百万个受影响程序中的一个为例,在流行的游戏 Minecraft 中,只需发送一条聊天消息就足以在游戏服务器上实现远程代码执行。因此,Minecraft 是一个受开源软件供应链漏洞影响的闭源程序的例子。由于几乎所有闭源程序都使用开源组件,它们都依赖于良好的开源软件供应链安全。

一个细微的区别是,涉及恶意编写代码的攻击与涉及无辜错误的漏洞是有区别的。例如,2021 年苹果修复了一个漏洞,该漏洞允许通过发送带有特别定制的图像附件的 iMessage 来实现所谓的零点击接管 iPhone 设备。附件自称为 GIF,但实际上是一个包含 JBIG2 图像的 PDF。苹果的软件使用了开源的 Xpdf JBIG2 解码器,该解码器是用 C 语言编写的,而这个解码器没有正确验证图像中的编码 Huffman 树;这使得攻击者能够在分配区域之外的控制偏移量处触发内存中的位操作。攻击者利用这些位操作实现了一个完整的虚拟 CPU,然后在虚拟指令集中编写代码来扫描进程内存,跳出 iMessage 沙盒,并接管电话。

JBIG2 漏洞是意外(而非恶意)引入的,因此它是一个开源软件供应链漏洞,而不是攻击。漏洞和攻击是不同的问题,具有不同的潜在解决方案。

作为另一个例子,2018 年研究人员发现 npm 软件包 event-stream 中包含隐藏的代码,当其被链接到 Copay 移动应用时,会窃取比特币钱包。这段恶意代码明确针对 Copay,使该应用成为受开源软件供应链攻击影响的闭源程序的例子。

尽管最后两个例子最终影响了闭源应用,对纯开源软件栈的攻击也是可能的。xz 攻击正是这样做的,它通过 OpenSSH 软件供应链的一个组件 ——liblzma—— 攻击了 OpenSSH,而不是直接攻击 OpenSSH 的源代码或项目本身。即使是纯开源攻击也可能造成毁灭性的后果:如果在其被发现之前再过几个月,被后门化的 sshd(Secure Shell 守护进程)就会在全球敏感环境中部署。

尽管没有一劳永逸的解决方案,但本文的剩余部分将突出工程更好防御的一般主题以及目前正在采取的实用步骤。

理解软件供应链

为了确保您的软件供应链安全,您首先必须了解它是什么。让我们从定义开始:软件供应链 是软件供应链攻击可能发生或漏洞可能被引入的所有地方。然而,理解 的更重要意义是知道您特定的软件供应链是什么样子,而这实际上非常困难。单词 chain 听起来很简单,但供应链就像分形:无论您多么仔细地观察,它都是复杂的。

在最低层面,您可以查看构建单个程序所执行的命令以及这些命令之间的依赖关系。这些构建图与程序本身的包依赖结构相一致。即使是简单的程序,这些图也复杂到无法打印出来。

Go 项目将避免不必要的依赖并保持软件简单作为一项优先任务,然而,在我撰写本文时,构建 go 命令需要执行 714 个命令来构建 297 个包,其包图中有 3,132 条依赖边。go 命令不同寻常,因为它没有外部依赖:它所使用的所有包都是 Go 项目本身的一部分。观察一个稍微复杂一些的命令,Kubernetes 的 kubelet 在其构建中执行了 3,289 个命令,并依赖于 137 个 Go 模块中的 1,581 个包,其中包括许多来自 Kubernetes 项目外部的包。

这两个例子都是相当小的、低层面的实用工具。更高层次的程序甚至有更复杂的构建。在本期《acmqueue》的另一篇文章中,Josie Anugerah 和 Eve Martin-Jones 详细探讨了开源构建图的复杂性,以及大多数程序都有许多可能的构建图这一令人惊讶的事实,这取决于它们构建的确切上下文。

这类依赖图很容易让人误以为这就是整个软件供应链的全部,但实际上它们只是最显而易见的一部分。依赖图中的每个包或模块可能由不同的人或组织编写,他们可能拥有不同的安全实践、代码审查标准等等。了解每个依赖项的这些细节会有所帮助,但通常这些信息是不可用的,并且随着时间的推移可能会发生变化。

另一种图表展示了软件在构建过程中以及向用户分发过程中所经过的计算机和服务。在这些计算机或服务中的任何一个上进行的恶意修改都可能成为不同的潜在攻击点,更不用说它们可能成为漏洞的潜在来源。你应该关注谁有权访问每个依赖项目,未来谁可能有权访问,他们使用的基础设施是什么,等等。在很大程度上,如果没有对这些信息的可见性,它们就会被忽视。但所有这些仍然存在。

了解软件供应链对于确定哪些环节需要加强至关重要。作为一个行业,我们在这里还有许多工作要做,但为了这篇文章,让我们继续探讨已经知道可以帮助加强的具体措施。

验证软件

Multics 审查曾考虑在 “分发阶段” 插入后门,利用 “不安全的电信” 以及发送带有伪造信笺的恶意更新。虽然措辞可能已经过时,但思想本身并未过时。XcodeGhost 就是这种方法的现代例子。解决这个问题是现代软件供应链安全领域最接近真正成功故事的事情。加密签名使得在签名和验证之间恶意篡改代码变得不可能。唯一剩下的问题是密钥分发:验证者必须知道谁应该对代码进行签名。

关于密钥分发问题,有许多可能的解决方案。最简单的一种是忽略身份问题,仅仅记录和分发在特定构建或包管理器中使用的特定依赖版本的预期加密哈希值。这些预先分发的哈希值的验证完全消除了下载服务器、代理和其他网络中间节点作为潜在攻击点的可能性。Debian 的依赖项打包系统包括这样的检查,这意味着 xz 攻击者不能简单地修改现有的 xz 副本;他们需要发布一个新版本。这并没有阻止攻击,但它确实使得攻击变得更加困难。

在更大规模上,而不是预先分发所有这些哈希值,它们可以保存在一个可信的数据库中。Go 校验和数据库是一个现实世界中的例子,该例子采用了这种方法,保护了数百万名 Go 开发者。该数据库包含了每个公共 Go 模块每个版本的 SHA256 校验和。每个数据库条目都由数据库服务器的私钥签名。相应的公钥在 Go 命令源代码中硬编码,因此密钥分发依赖于 Go 分发的其余部分。

每次执行 go 命令下载新的开源 Go 包时,它都会查找预期的校验和。对于给定项目中的依赖项,存在一个本地的校验和缓存,因此只有在进行升级或添加新依赖项时才会发生对校验和服务器的网络调用,但无论如何,每个下载都会进行检查。这意味着在代码托管和用户计算机之间的所有代理和其他盒子都不能成为攻击站点。即使攻击代码托管站点,也无法更改旧包。

当然,有一个问题需要考虑,那就是将哪个校验和放入数据库中。对于 Go 语言来说,如果数据库还没有记录特定软件包的版本,它会直接获取代码并存储获取到的代码的校验和。这种 “首次使用即信任” 的方法并不意味着代码是可信赖的,但它确实意味着如果明天有人在另一台电脑上下载它,代码不会发生变化。这种不可变性确保了整个 Go 生态系统对 Kubernetes 版本 1.28.4 的含义达成一致,这为任何其他分析工作奠定了基础。

在解决身份问题的范围内,让作者为其软件签名可以提供更强的保证。以 xz 为例,发行版软件包使用了个别作者的 GPG(Gnu Privacy Guard)密钥进行签名,这使得可以区分由 xz 的原始(可信)维护者签名的软件包和由控制了项目的攻击者签名的软件包。

使构建可重现

Multics 审查指出,一个恶意的更改 “最好隐藏在编译例程的二进制代码更改中”,而相应的源代码则保持不变。这种更改只有在从源代码重新构建后才会持续存在,但大多数安装在没有理由的情况下不会重新构建源代码。这至今仍是一个问题。例如,在构建过程中触发 xz 攻击的关键代码行仅包含在打包的分发中,而不是实际的源代码控制库中。

验证二进制文件未被修改的最佳且最明显的方法是重新构建它们,并将结果与分发的二进制文件进行比对,但这假设构建过程是可重复的。由于计算机是确定性的,这似乎应该很简单,但实际上,由于构建机器的架构或机器名称、临时目录的名称或当前时间等上下文信息很容易出现在某些构建输出中,导致整体构建不可重复。可重复构建项目旨在提高人们对可重复构建的认识,同时构建工具以帮助所有 Linux 软件实现完全可重复构建的进步。

Go 项目最近安排了让 Go 语言本身在只有源代码的情况下完全可重现,这意味着尽管构建需要一个运行某些操作系统和某些早期 Go 工具链的计算机,但这些选择并不重要。针对特定目标的构建,无论是在 Linux、Windows 还是 Mac 上构建,无论是在 X86 还是 ARM 上构建,都会产生相同的分发二进制文件。强大的可重现性使得其他人可以轻松地验证发布的二进制文件与源代码是否匹配。这些二进制文件也记录在 Go 校验和数据库中,当 go 命令下载新的工具链时进行验证,以确保下载过程中无法修改。

验证软件和使构建可重现消除了潜在的攻击向量,尽管这当然不是全部。现在让我们将注意力转向漏洞。

快速发现和修复漏洞

五十年前,人们曾抱有一丝希望,认为通过正确的设计和谨慎的实施,可以使软件完全安全。如今我们深知这一点。既然我们承认软件始终存在漏洞,那么我们就必须做好准备,在漏洞出现时尽快发现并修复它们。

攻击者也在寻找这些漏洞,因此最好的防御策略就是先于他们发现并修复这些漏洞。最简单的例子是过时的依赖项,其中包含已知的漏洞。有许多可用的漏洞扫描工具可以识别这种情况,无论是特定语言的工具如 govulncheck 和 npm audit,还是通用的开源工具如 osv-scanner,或者是商业工具。所有这些工具的工作原理都是通过将构建软件的输入列表 —— 即 “软件物料清单”—— 与已知漏洞数据库进行交叉核对。

工具或数据库的具体选择现在并不像过去那样重要。开源软件社区已经将 OSV(开源漏洞)格式标准化,用于描述单个漏洞,包括受影响软件包和版本的精确、算法性描述。然后,OSV 数据库聚合了所有特定语言的数据库。CVE(通用漏洞与暴露)数据库的 JSON 5.0 架构也采用了 OSV 关于受影响软件包和版本的精确信息,使得 OSV 和 CVE 之间能够进行信息交换。对于所有工具都能访问关于已知漏洞的相同、完整信息,这对每个人都是有益的。

定期扫描您的软件非常重要,理想情况下是每天一次,因为即使您的软件没有发生变化,数据库中总是会有新的条目被添加。然后您需要准备好更新到该依赖项的修复版本。这需要进行全面测试以确保修复版本不会引入任何新的错误,以及拥有自动化部署,以便您的软件的修复版本可以在数小时或数天内发布,而不是数周或数月。

测试和部署是标准软件工程关注的问题,虽然它们并非专门关于供应链安全,但如果没有这些措施,您的安全态势会受到损害,您的法律风险也可能增加。当 2021 年发现 Log4j 漏洞时,大多数公司需要花费数周或数月(或更长的时间)来清点他们所有的软件,以确定哪些软件受到影响,然后更新和重新部署这些软件。

即使是美国联邦贸易委员会(Federal Trade Commission, FTC)也发布了一份声明,警告公司更新 Log4j 以 “降低对消费者造成伤害的可能性,并避免联邦贸易委员会的法律行动”,并指出了 Equifax 因未打补丁的软件导致的入侵而承担的前期责任。

扫描已知漏洞只是最低要求。理想情况下,还应该花费精力寻找你开源依赖项中尚未发现的漏洞。当你对自己的源代码进行安全审计时,识别关键的开源依赖项并对它们进行审计通常也是值得的。对你的软件及其依赖项运行漏洞发现分析工具或模糊器也可能是有效的。攻击者将会使用所有这些方法;你不妨先使用它们。

预防漏洞

尽管软件总会存在漏洞,但你可以采取一些措施来预防某些类型的漏洞或降低它们发生的可能性。

首先,避免不必要的依赖项。戈登・贝尔曾观察到:“[t] 计算机系统中成本最低、速度最快、最可靠的组件是那些不存在的组件。” 最安全的软件依赖项是那些一开始就没有使用的依赖项:每个依赖项都增加了风险。

OpenSSH 项目非常谨慎,避免承担不必要的依赖,但 Debian 并非如此。该发行版修补了 sshd,使其链接到 libsystemd 库,而 libsystemd 库又链接到了各种压缩包,包括 xz 的 liblzma 库。Debian 对 sshd 依赖性的放宽是攻击的关键触发因素,也是其影响仅限于基于 Debian 的系统(如 Debian、Ubuntu 和 Fedora)的原因,避免了像 Arch、Gentoo 和 NixOS 这样的其他发行版。

在 xz 攻击部署几周前,系统开发者一直在讨论移除对 liblzma 等压缩器的依赖,特别是为了提高安全性。这只是一种纯粹的猜测,但这些讨论可能加速了攻击的部署时间表。

同样的教训适用于所有项目,无论大小。如果可能的话,没有依赖项通常是最好的选择。如果不行,小依赖项比大依赖项更好,并且传递依赖项的数量也很重要。不仅要看新增的一个依赖项,还要看它对整体依赖图的影响,可以使用像 Open Source Insights 这样的工具。另一种预防漏洞的好方法是使用更安全的编程语言,这些语言移除了容易出错的特性或使这些特性变得不那么频繁地被使用。

在 2022 年,美国国家安全局(NSA)发布了一项关于 “软件内存安全” 的建议,鼓励使用内存安全语言,如 C#、Go、Java 或 Rust,而不是 C 和 C++。在 C 和 C++ 的众多缺点中,手动内存管理和缺乏任何类型的边界检查使得程序过于容易出错,从而创造出安全漏洞。它们对 “未定义行为” 的依赖又增加了另一个危险层级。当然,世界上有大量的 C 和 C++ 代码,这些程序不可能一夜之间就被放弃。然而,对于新的努力,采用更安全的语言具有显著的安全优势。

支持开源

2020 年著名 xkcd 漫画描绘了 “所有现代数字基础设施” 都是建立在 “内布拉斯加州某个随机人员在 2003 年以来默默维护的项目” 之上。这幅漫画对现状的描述令人不安。

2014 年,研究人员发现,OpenSSL 库,这是一个被互联网 HTTPS 服务器广泛使用的库,会对一种特定的损坏数据包做出响应,发送回服务器内存的任意块。在某些情况下,这些内存包括服务器的密钥材料。这不是一次攻击,而是一个无辜的编码错误(OpenSSL 是用 C 语言编写的,因此这个错误很容易犯而且难以发现;在一个内存安全的语言中,带有适当的边界检查,这种情况几乎不可能发生。)

该漏洞被命名为 “心脏出血”,并促使整个行业重新审视了 xkcd 漫画中所描述的 precisely the situation。当时 OpenSSL 由少数志愿者维护,只有一名全职开发者。研究人员估计,一次大约需要 10 万美元的安全审计就能捕捉到这个错误,但该项目每年只收到了 2,000 美元的捐赠,尽管每年有数十亿美元的商务依赖于这款软件。

这次重新审视的一个结果是,Linux 基金会成立了核心基础设施计划(Core Infrastructure Initiative),后来演变成了开源安全基金会(Open Source Security Foundation,简称 OpenSSF)

OpenSSF 是一个重要的进步,但它并没有解决现代数字基础设施依赖于资金不足的关键项目的问题。还需要做更多的工作。

xz 攻击是最清晰的证明,表明问题并未得到解决。它之所以得以启用,既是因为开源项目资金不足,也因技术细节的问题。以下是 xz 攻击的故事。

Lasse Collin 于 2005 年启动了 xz 项目,该项目使用了 LZMA 压缩算法,将文件压缩到 gzip 的约 70%。随着时间的推移,这种格式被广泛用于压缩 tar 文件、Linux 内核镜像以及其他许多用途。总的来说,该软件稳定可靠,不需要持续的大量关注。Collin 并未因此获得报酬,这也不是他的全职工作。

2021 年底,一名使用(几乎肯定不是真实)名字 “Jia Tan” 的攻击者开始在 xz 开发邮件列表上发送无害的补丁,这些补丁包含了一些小的改进。2022 年中,该攻击者开始在邮件列表上使用其他账户和名字发帖,抱怨发布速度缓慢和新功能的缺乏,并施压要求 Collin 将控制权交给更有时间的人。他们写道:“当前维护者失去了兴趣或不再关心维护。看到这样一个仓库如此令人遗憾。” 还有,“我明白这对所有贡献者来说都是一个爱好项目,但社区希望得到更多。为什么不传给其他维护者……?”

压力攻势取得了成效。在接下来的一年半时间里,柯林将越来越多的开发责任交给了这位攻击者,攻击者通过进行诚实的改进和完成重要的维护工作赢得了信任。2023 年初,这位攻击者发布了他们的第一个官方 xz 版本;随着 2023 年的推进,他们为实际的攻击打下了技术基础,最终在 2024 年初发起了攻击。

在攻击被发现后的几个月里,大多数猜测都集中在 xz 攻击很可能是由国家黑客实施的这一可能性上,但双方都没有确凿的证据。无论责任在谁,这很可能并没有花费太多。一名合格的软件工程师全职在开源项目上工作两年以赢得维护者的信任,可能花费不到一百万美元。开发本身相当复杂的漏洞利用代码可能又要花费大约一百万美元。一个隐藏的后门,可以进入互联网上绝大多数 Linux ssh 服务器,其价值可能远超过这些,可能是数十亿美元。开源项目的普遍资金不足使它们直接容易受到这种看似诚实的免费帮助的影响。

xz 攻击的社会工程学也不是一个孤立的事件。在前面提到的 event-stream 攻击中,攻击者只是简单地询问原作者是否希望有人接管维护。xz 攻击之后,OpenSSF 和 OpenJS Foundation 发布了一则警告,关于一个针对 OpenJS 未遂进行的类似活动。

如何最好地资助开源开发远非显而易见。在 Heartbleed 漏洞和 Core Infrastructure Initiative 启动十多年后,这个问题显然仍未得到解决。

结论

我们都正在努力应对在过去十到二十年里软件行业发生的巨大转变。几十年来,软件重用只是一个宏伟的目标。而现在,这已经成为现实。现代编程环境,如 Go、Node 和 Rust,使得重用他人的工作变得轻而易举,但我们的责任感本能尚未适应这一新现实。

1974 年 Multics 审查预见到我们今天面临许多问题的现实,证明了这些问题是根本性的,并且没有简单的解决方案。我们必须努力不断改进开源软件供应链的安全性,使攻击变得越来越困难和昂贵。

我们今天可以采取的重要步骤包括,以某种形式采用软件签名,定期扫描已知漏洞,并在发现关键新漏洞时准备好更新和重新部署软件。越来越多的开发应转移到更安全的语言,以降低漏洞和攻击的可能性。我们还需要找到方法来资助开源开发,使其不太可能仅仅因为提供免费帮助而被接管。对 OpenSSL 和 xz 开发的相对较小投资本可以防止 Heartbleed 漏洞和 xz 攻击。

xz 攻击似乎是对开源软件供应链的首次重大攻击。event-stream 攻击类似,但并非重大,而 Heartbleed 和 Log4j 是漏洞,而不是攻击。但 xz 攻击实际上是被偶然发现的,因为它使得 sshd 在启动时速度变得略微缓慢。攻击的本质是试图保持隐蔽。我们有多大几率会在几周内意外地发现对开源软件供应链的首次重大攻击呢?也许我们非常幸运,或者也许我们错过了其他攻击。

Multics 的审查因其指出向编译器添加后门的可能性而闻名,这种后门可以在编译过程中将后门插入关键系统程序中,正如 XcodeGhost 后来所做的那样,以及编译器自身可能成为后门的可能性,这样修改就会在编译器完全重新编译后仍然持续存在。阅读这份报告启发了 Ken Thompson 在 1975 年早期对早期 Unix 系统实施这种攻击。他在 1983 年的图灵奖演讲中解释了这种攻击,该演讲发表在《ACM 通讯》上,题为 “信任的反思”。Thompson 保留了原始攻击源代码,并在他的许可下,我在 2023 年 11 月发布了一个带注释的副本。最令人不安的部分可能是它的简短:99 行 C 代码和 20 行 shell 脚本。

在他的讲座中,汤普森说:“道德显而易见:你不能信任你自己没有完全创造出来的代码。” 但如今,我们每天都在做这样的事情,不论这种信任是否合理。我们在最关键的应用中使用了从互联网上陌生人那里下载的源代码;几乎没有人检查这些代码。

劳伦斯・凯斯特洛特的优秀短篇小说《编码机器》想象了一个受到汤普森后门攻击的计算机世界。在我们实际的世界中,这种后门的复杂性根本不是必要的。有更简单的方法可以进行供应链攻击,比如问维护者是否需要一些帮助。如果能生活在一个需要汤普森和凯斯特洛特描述的那种复杂性的攻击的世界里,那会很好。

我们都有更多的工作要做。


2025年开源状况报告:保持软件更新为头号挑战

根据 Perforce Software、Eclipse 基金会和 OSI 发布的《2025 State of Open Source》,当被要求按 1 到 5 的等级对挑战进行排名时,433 名受访者中超过一半的人将以下挑战评为 3 分或更高:
保持软件更新
满足安全性和合规性要求
维护停产 (EOL) 版本
报告作者写道:“这三者当然紧密相连 —— 及时更新和修补程序,并维护已停产的版本,是满足安全性和合规性要求的关键。每年对这个问题的回答都提醒我们,对于组织而言,保持最新版本和 / 或获取其堆栈中已停产软件的安全更新和补丁,是一场艰苦的战斗。”

例如,CentOS 7 于 2024 年 6 月达到 EOL,在进行调查时(2024 年 9 月至 12 月之间),40% 的大型企业仍在使用它,它是第三大最常见的 Linux 发行版。

此外,28% 的受访者表示没有针对 CentOS 漏洞的修复计划,8% 的受访者表示不打算修补 CentOS 的 CVE(常见漏洞)。只有 19% 的受访者表示有 LTS 厂商提供补丁,13% 的受访者表示有内部团队负责补丁。

当使用专有版开源软件的受访者被问及是什么阻碍了他们使用开源版本时,44% 的受访者表示是开源软件附带的专业支持和维护,占比遥遥领先;其次是附加功能和定制化,占比 25%。

开源软件的使用场景


报告显示,使用开源技术最多的类别是云和容器技术,40% 的受访者在该领域使用开源软件。最受欢迎的云原生开源项目是 Docker(59% 的受访者使用)和 Kubernetes(39%)。

数据库和数据技术是第二大最常用的开源软件,占受访者的 33%。最受欢迎的是 PostgreSQL(51%)、MySQL(37%)和 MariaDB(31%)。

报告发现,近一半的组织对其数据管理运营缺乏信心。当被要求将他们对大数据管理的信心从 1 到 5 进行评分时,47% 的受访者给自己打了 2 分或更低的分数,不到 10% 的受访者给自己打了 5 分。

使用开源数据库或其他数据技术的最大挑战是缺乏人员或人员经验,有超过四分之三的受访者这样认为。

出于这个原因,一些人转向商业托管解决方案(例如 Cloudera),但代价是成本。如果组织无力承担商业托管平台的费用,他们就只能承担这些复杂堆栈的运营和人员成本,往往需要依靠经验不足的 DevOps 工程师,或者在无法解决问题时求助于外部顾问。

今年使用开源软件最多的第三大类别是编程语言和框架(33%),比上一年有所增加。报告作者认为,这表明越来越多的组织正在开发开源软件,而不仅仅是使用它。

报告指出,开源编程语言是拥有 1-20 名员工的小型公司的首要投资领域,这表明他们正在内部创建自己的解决方案。规模最小的组织对开源项目的贡献也远超拥有 5,000 名或以上员工的大型组织。小型公司贡献率高达 57%,而大型公司仅为 25%。

OSI 执行董事 Stefano Maffulli 表示,“报告表明,大型企业在开源战略方面并不一定更成熟。令人鼓舞的是,即使是规模很小的组织也不仅致力于使用开源软件,还通过贡献代码和支持开源软件基金会来回馈社区。”