本内容是对Go项目负责人Russ Cox 在 ACM SCORED 活动上演讲内容[1]的摘录与整理。
SCORED 是Software Supply Chain Offensive Research and Ecosystem Defenses的简称, SCORED 23[2]于2023年11月30日在丹麦哥本哈根及远程参会形式举行。
摘要
-
💡 谷歌在开源软件供应链安全方面的工作 -
🔐 介绍供应链安全概念和不同类型的攻击案例 -
🔄 加强理解软件供应链,探索构建、分析方法 -
🛠 使用加密签名、构建可重现的构建流程保障供应链安全 -
🧰 提倡内存安全编程语言如 Go 和 Rust -
📊 推动开源安全标准(SLSA)、安全评分卡和漏洞监测工具发展 -
🧾 探讨软件 BOM(Bill of Materials)的定义和监测工具对已知漏洞的重要性 -
🚀 呼吁对软件供应链进行更多研究和标准化
全文
大家好,我是 Russ Cox,我在 Google 工作,我是 Go 编程语言的技术leader。
我们Go工作的一个重要部分, 是确保它是一个安全的编程环境。因此,我们在供应链安全方面投入了大量的时间和努力。我今天的目标是让你了解Google在供应链安全方面的整体努力,并强调我认为需要进一步(投入更多)研究的领域。如果你想了解更多或参考这些内容,这些幻灯片已经发布在go.dev/s/acmscored [3]上。
今天的演讲主题是Google的开源供应链安全。首先,让我们了解一下“供应链安全”到底是什么意思。通常,当我们谈论供应链安全时,是指针对供应链攻击的工程防御。现在,我们需要定义什么是供应链攻击。虽然没有一个普遍接受的定义,但Kim Zetter曾经将供应链攻击定义为对可信软件在其源头进行的恶意更改,这个定义几乎是完美的。
(何为开源供应链安全?软件本身不一定是开源的,但用到的出现问题的组件需要是开源的)
我在其定义中添加在交付之前,因为这些更改不是在传输过程中发生的,这是供应链攻击与传统攻击的根本区别。例如,如果我晚上闯入你的办公室并更改你计算机上的软件,那就是一次常规攻击。但如果我闯入你的软件供应商,并在那里更改软件,那就是一次供应链攻击,因为这种更改是在我们接触软件之前发生的。
历史上有一些涉及物理设备的供应链攻击案例。比如,1967年,美国中央情报局(CIA)说服瑞士公司Crypto AG向多个国家出售带有CIA设计缺陷的电子加密设备。事实上,CIA后来购买了这家公司,并直接执行该操作并持续了50多年,直到2018年才结束。这些设备几十年来一直是美国及其盟国的重要情报来源。
与之相比,第二次世界大战期间,盟军发现了德国恩尼格玛加密机的设计缺陷,并利用这些缺陷设计了一个解密流程。这不是供应链攻击,而只是利用了设计上的缺陷。
在2015年,针对X国托管的文件共享网站上下载速度更快的Xcode副本,攻击者发布了一份链接器被恶意修改过的Xcode副本。这个修改过的链接器会将恶意代码添加到它构建的每个iOS应用程序中。这个被修改的Xcode版本后来被安全研究人员命名为XcodeGhost。根据相关报道,2012年,许多应用程序开发人员下载并使用了包含恶意代码的程序,这些应用程序被发送给许多iOS用户.
译者备注:
XcodeGhost源码地址[4]
相关报道[5]
苹果手机病毒感染事件——震惊业界的 XcodeGhost[6]
XcodeGhost风波[7]
再进一步的例子包括 瞻博网络[8](Juniper Networks)遭受的攻击。疑似来自X国的黑客组织闯入瞻博网络并更改了其VPN源代码,替换了随机数生成器中的一些关键常量. 其效果是创建了一个后门,使攻击者能够解密进出这些设备的所有VPN流量。这是一种供应链攻击,因为它在将软件交付给用户之前更改了软件。讽刺的是,由于来自美国政府的压力,随机数生成器首先是可后门的。这可以被视为算法供应链攻击.
2019年9月,疑似来自俄罗斯的黑客组织闯入了名为SolarWinds[9]的公司的构建服务器,当Orion更新时(译者注:该一个网络管理平台),他们将恶意代码注入到SolarWinds监控软件的构建中,该黑客组织获得了对多个政府敏感网络的访问权限。
专访SolarWinds:遭受黑客攻击 给一家软件公司带来了什么[10]
这些例子都不涉及开源软件。让我们将开源供应链攻击, 定义为对在受信任程序中使用的受信任开源组件的恶意更改。请注意,受信任软件不需要是开源的,只有恶意代码必须开源。
例如,2018年11月,npm event-stream
包被发现包含恶意代码,当链接到copay移动应用程序时,该代码会盗取比特币钱包。copay是开源的,但事件流是开源的,所以这是一个开源供应链攻击。代码在两个半月的时间里都没有被发现,你知道攻击者是如何开展行动的?他们只是问作者是否希望他们接管代码的维护,得到的回复是"是的,非常感谢"
篡改 npm 包盗取比特币始末[11]
但并发所有的供应链问题都是攻击, 除了供应链攻击之外,还有供应链漏洞。例如,2021年9月21号,苹果修复了一个错误,该错误允许通过发送带有特制图像附件的iMessage来实现所谓的iPhone设备的零点击接管。(该附件)声称是一个gif,实际是一个包含JBIG2的pdf
谷歌安全研究员直呼复杂 | iMessage 零点击漏洞利用细节公开[12]
1张GIF图片即可黑进iPhone!谷歌团队叹:最复杂的漏洞之一![13]
Apple的软件使用了用C语言编写的开源xpdf jbig2解码器,并且该解码器没有正确验证图像中编码的霍夫曼树,从而可以触发攻击者控制偏移处的内存。除此,攻击者通过按位运算实现了整个虚拟CPU,然后在该虚拟指令集中实现了代码来扫描进程内存,突破了iMessage沙箱并接管了手机中存在缺陷的xpdf C代码,启用了此攻击.但据我们所知,这个错误并不是恶意引入的,因此不算供给链攻击.
类似地,2021年晚些时候, Minecraft玩家发现,发送特制的聊天消息会导致Minecraft从他们的远程服务器下载并执行Java代码。这用来对他们的朋友进行大多无害的恶作剧,但攻击者很快意识到,这是由于log4j日志包中的功能(问题),后来被武器化。
xpdf 中的问题是一项错误,log4j中的问题是一个功能,他们都不是恶意的,但是都是供应链的重要组成部分.因此让我们扩大供应链漏洞的定义,将开源供应链漏洞定义为由开源组件引起的可信软件中的可利用弱点。
请注意,可信软件不必是开源的 ---
Minecraft不是,但log4j是,所以我们仍然可以说Minecraft存在开源供应链漏洞。
现在我们可以将开源供应链安全定义为防御开源供应链攻击和开源供应链漏洞的工程。这就是本次演讲的内容,花了一点时间,但我认为这是值得的,因为这个定义在开始时对我来说还很不清楚,我希望它也能帮助你了解开源供应链。
我先做两个重要免责声明:
首先谷歌是一家庞大的公司。虽然我会提到我们的许多努力,但有些项目还不适合公开讨论,或者还没有准备好公开。因此,请不要将我的话解读为对这些项目的详尽解释。
此外,很多优秀的公司也在这一领域开展工作,我们的某些工作可能与其他公司的工作有所重叠,但这并不意味着对他们的批评。供应链安全是整个行业都在努力解决的问题,我们都在寻求有意义的进步。今天,我将重点介绍谷歌在软件供应链安全方面的工作。
总体来说,我们的方法分为三个部分:了解供应链、加强供应链和监控供应链。
首先,为了保护我们的软件供应链,必须清楚地了解它的构成。这不仅仅是定义上的理解,虽然我们还没有正式定义它。我们应该把它定义为可能发生供应链攻击的所有环节。理解软件供应链的真正意思是了解它的构成、攻击可能发生的位置以及我们如何表示或分析软件供应链。
问题在于,“链”这个词听起来很简单,但实际上供应链的复杂性就像分形一样,无论你观察到多么微观的层面。例如,我们可以查看单个程序的构建图,如Google Protocol Buffers编译器的构建依赖关系图。这是一个相对简单的C++程序,但即使这样,依赖关系图也显示了复杂性,图中有超过500个节点和3000多个边。这只是放大了一小部分内容的示例,实际的程序会有更大的图形。
另一张图是展示源代码在构建期间经过的机器和服务。几年前,我在检查Go二进制发行版下载的供应链安全性时绘制了这样一张图。图中每个圆角矩形代表一个不同的程序,涉及准备二进制发行版的过程。这种图表可以帮助我们识别并解决潜在的安全问题。
另一种图表是依赖关系图, 展示了构建过程中使用的不同开源组件。例如,这里展示的是Kubernetes的依赖关系图,根据Google的开源洞察项目,图中有数百个节点,每个节点代表一些相关的机器集合,就像前一张幻灯片所示。每个节点都是一个潜在的攻击点,更不用说这些点可能暴露的潜在漏洞了。
在探讨软件供应链安全性时,我们首先需要关注谁有权访问这些系统。对于每个项目,我们应考虑谁可能会在未来访问他们使用的基础设施。然而,在大多数情况下,我们对这些访问权限没有可见性,尽管它们非常重要,我们往往会忽视它们。这是一个挑战,但我们正致力于解决它。
过去几十年,特别是在最近的10到20年内,软件行业经历了巨大转变。软件复用,从一个理想化的目标变成了现代编程环境的一个实际现实。例如,在Go、Node和Rust这样的环境中,重用其他人编写的代码,如Kubernetes所依赖的来自200个模块的3000个包[14],变得非常普遍。然而,我们对这种重用行为的本能反应尚未适应这一新现实。
(https://deps.dev/) 的目标是使这种重用 变得可见,并能够用于进一步的分析。例如,通过比较不同版本的Kubernetes依赖关系[15],我们可以发现其中的安全漏洞。Kubernetes版本1284中的两个已知安全漏洞,其中一个在1290版本中已经被解决,但另一个仍然存在,即使包含它的依赖项已经升级。
我们面临的一个重要研究问题是如何将这些信息转换成机器可读的形式,以便我们能够分析所有内容并识别当前存在的弱点。我相信,我们对某些部分的了解已足够识别重要的弱点,并努力加强这些弱点。然而,更全面的供应链系统分析几乎肯定会发现新的问题。
在加强软件供应链的过程中,我们的目标是设计出对抗攻击者的攻击和漏洞的防御措施。我们希望找到方法来减少潜在的攻击点,并在攻击者使用它们之前,甚至首先阻止它们发生。
其中最有效的加强措施之一是加密签名,它确保在签名和验证之间代码无法被恶意更改,从而消除了下载服务器、代理和其他网络中间设备作为潜在攻击点的可能性。然而,这并不是没有成本的,它引入了密钥分发的问题,尤其是验证者必须知道谁应该对代码进行签名。
举个例子,数百万Go开发者使用的数据库保存着每个公共Go包每个版本的SHA-256校验和,每个数据库条目都由数据库服务器的私钥签名,相应的公钥被硬编码在Go命令的源代码中。因此,密钥分发与Go发行版的其他部分紧密相连。每次Go命令下载新的开源Go包时,它都会检查预期的校验和。对于给定项目中的依赖项,有一个本地校验和缓存,因此对checksum服务器的网络调用仅发生在升级或添加新的依赖项时,
这种方法检查每个下载,确保代码托管和用户计算机之间的所有代理和其他中间层无法修改代码。即使有人攻击代码托管站点,也无法更改已经存在的包。
如果数据库中尚未记录特定的包版本,系统会直接获取该代码并存储它的校验和。虽然这并不意味着该代码本身就是可信的,但它确保如果其他人在未来在不同的计算机上下载同一代码,代码内容将保持不变。这种不变性对于确保整个Go生态系统,包括Kubernetes版本1284,对代码的理解一致至关重要。
Google帮助创建的另一个项目是sigstore[16],这是Go checksum 数据库的一个公共和更开放的版本。sigstore允许任何人发布数据库记录,然后用户可以读取并验证这些记录。尽管sigstore主要是供开发人员发布代码和最终用户验证代码使用,但实际上大多数最终用户并不直接与之交互。sigstore作为一个通用校验和数据库,为软件包生态系统提供服务,而不需要各个系统运行自己的校验和数据库。据我所知,npm生态系统已经开始与sigstore进行初步集成,虽然这一功能默认尚未启用(因此还没有产生太大影响),但这是向更安全的软件供应链迈出的重要一步。
当然,运行所有这些服务的计算机和构建机器也需要保护。这主要涉及常规计算机安全措施,虽然这些措施并不专门针对供应链,但它们是实现更高级供应链安全措施的重要基础。确保所有相关的构建步骤都在专用的安全构建系统上进行至关重要,包括使用Google Cloud Build或GitHub Actions等云服务,而不是在单个工程师的工作站上进行。专用构建机器通常可以更好地加强安全,因为它们不需要运行Web浏览器、聊天软件或工程师日常工作所需的其他软件。
在软件工程中,没有任何解决方案是完全免费的,这也适用于工程工作站的安全保护。如果不采取适当的保护措施,攻击者可能会在工程师工作时修改源代码。因此,建设和加固专用的构建机器(Mach机器)变得至关重要,以降低任何单一构建机器的重要性。
一个有效的方法是确保构建的可重复性,即使用相同的工具多次构建相同的代码应产生相同的输出。这看似简单,但实际上很容易因构建机器的架构、机器名称、临时目录的名称或当前时间等上下文信息而变得复杂,从而影响构建的可重复性。
具有可重复性的构建允许在多台机器上运行构建并检查结果是否一致。例如,我们最近安排的Go构建是完全可重复的,仅基于源代码。这意味着无论是在Linux、Windows还是Mac上构建,无论构建主机是x86还是ARM,都会获得相同的发行版。这种强大的可重复性使其他人可以轻松验证我们发布的二进制文件与源代码是否匹配。我们还开始将这些二进制文件记录在checksum数据库中,并在Go命令下载新工具链时进行验证,以确保下载内容在传输过程中未被修改。
除了重复构建外,还有其他流程改进措施,可以使开源代码存储库和构建过程更加安全。其中最重要的一项是消除对源代码的单方面访问,并在Google构建系统中实现双重审核。规则是对生产代码或系统的任何更改都需要至少两名员工的协同操作,类似于军方发射核武器所需的双重确认。对于Go这样的开源项目,通常需要代码作者和代码审查者的协调。如果代码作者不是Google员工,则需要两名Google员工审查更改。
在Google的内部身份验证系统中,访问生产或构建系统也需要两名员工的协调。这种流程改进(例如可重复构建)和双重审批同样重要,就像保护构建机器和代码存储库一样。然而,要确定一个项目是否实施了这些措施可能很困难。
Google推动的开源供应链安全方法包括鼓励项目采用并记录最佳构建实践。Google是开源安全基金会(OpenSSF)的创始成员之一,并通过该组织定义了一个名为SLSA的标准[17],代表软件工件的供应链级别。SLSA为构建的安全性定义了四个级别,从零级(最低级别,无保障)到第一级(需要自动化运行并至少提供文档形式的出处),再到更高级别的要求,如加密签名和构建输出的加密哈希。
此外,还有针对开源流程改进的努力,如安全记分卡。这是一个工具,可在GitHub存储库上运行,检查对各种最佳实践的使用情况并进行评分。记分卡检查项目包括是否启用了GitHub的分支保护功能,以及存储库的自动化流程是否使用具有不必要权限的访问令牌。记分卡的目标是供应链安全而不是代码质量,这是一个独立的目标,需要以不同的方式进行衡量。对记分卡中激励的重要内容和对实际存储库及其影响的研究是值得进一步探索的领域。
安全性在软件开发中是一个至关重要的领域。最近,一个名为“Caps Lock”的项目被专门用来监控攻击。它分析开源软件包,以确定它们可能使用的敏感系统服务。在一个示例中,Caps Lock显示了我正在分析的软件包使用了我未预期的os.read
来读取系统状态,以及getet inv
。Caps Lock还报告了在排序调用中丢失的间接路径。这个项目尚处于实验阶段,仅有几个月的历史,但它展现了一个愿景,即使用这个工具来评估新依赖项的采用,并监控现有依赖项在升级时是否引入了新功能。
Caps Lock的限制之一是,即使在它的预期功能范围内,通用代码系统仍然可能执行恶意操作。例如,如果你控制了作为依赖项的yaml解析器,你可能会找到办法调整解析器返回的配置,从而改变访问控制列表或防火墙规则。Xcode Ghost就是一个例子,它在系统调用或其他功能级别上没有做任何与普通Xcode不同的事情,但却改变了它编译的程序的含义。
沙箱等运行时强制能力系统也不是使用不受信任代码的万能解决方案,但它们仍然可以成为重要的工具。我们的目标是防止故意攻击和意外漏洞。谷歌通过各种方式资助外部安全工作,包括错误赏金和补丁奖励。我们还有一个名为Project Zero的内部团队,专门用于发现任何广泛使用的重要软件中的漏洞,不仅仅是谷歌的软件。
在开源方面,谷歌启动并资助了OSS模糊测试项目,该项目对重要的开源项目进行连续模糊测试,并报告自项目启动以来发现的漏洞。OSS模糊测试已发现超过10,000个漏洞和超过36,000个错误。谷歌还运行了一个单独的模糊测试服务,专注于通过精心设计的随机系统调用来破坏操作系统。它主要集中在Linux上,模糊测试已经发现了近 5000 个真实的内核漏洞。截至本周,其中约有 800 个漏洞已经得到修复,但数以千计的其他问题仍未解决。
这些数字令人担忧。即便采用现代的覆盖率指导技术,模糊测试仍然十分复杂,就像用石头敲打代码一样。它发现漏洞的效力,可以看作是对现代软件实践的严厉指责。
本月是互联网蠕虫之父罗伯特·T·莫里斯[18]创造第一个蠕虫病毒 35 周年。《纽约时报》援引他父亲、美国国家安全局前首席科学家罗伯特·H·莫里斯的话说,莫里斯蠕虫在很大程度上提高了公众的安全意识,并促使人们对蠕虫病毒更加重视。
事后看来,我认为大多数预期的负面影响并未发生。我们不能继续玩”缓冲区溢出猫鼠游戏”,并在发现漏洞后掉以轻心。我们必须找到更系统的方法来改进。具体而言,我们需要停止使用 C 和 C++,转向内存安全语言。NSA 去年就赞同我的这一观点,他们建议从 C 和 C++ 转向我们在 Google 专门创建的内存安全语言Go,以避免现代 C/C++ 的许多问题。
安全性是我们设计 Go 语言时最先考虑的事项之一。在 Go 中,所有数组边界都会检查,语言级竞争也不会引发任意未定义行为。程序员可以编写类型不安全的代码,但必须导入名为 unsafe 的特殊包。导入 unsafe 同时也会触发编译器的警告。总的来说,我们希望通过语言设计鼓励更安全的编程。
Rust 是另一种重要的新型安全语言。Google 已大举采用 Rust。2021年,Rust 被纳入 Android 作为官方语言。从那时起,被添加到 Android 的新代码中有超过 20% 是 Rust。这是 Linux 在 2022 年开始接受 Rust 代码进入主内核的原因之一。Chromium 也于 2023 年开始接受 Rust 代码。Go 和 Rust 都是从 C/C++ 升级的绝佳选择。
评估语言安全性的一种方法是查看该语言中严重漏洞的情况。在 C/C++ 中,典型的严重漏洞是缓冲区溢出或释放后使用,可导致远程代码执行,如互联网蠕虫或 iMessage 攻击。Java 比 C++好得多,因为它有数组边界检查,并且像 Go 那样不能引发任意未定义行为。然而,Java 仍可导致大量未定义行为。复杂的代码反射和动态代码加载,以及 Java 开发人员找到利用这些功能的方法,在日常使用中虽功能强大,也可实现强大攻击。因此,尽管 Java 有语言级安全性,像 2017 年的 Apache Struts 或 2022 年的 Log4J 漏洞仍可导致远程代码执行。
相比之下,典型的严重 Go 或 Rust 漏洞仅导致拒绝服务攻击,如格式错误或过大输入导致解析代码恐慌或使用过多 CPU/内存。这些问题相比 C/C++ 和 Java 中的远程代码执行明显轻微。因此,Go 和 Rust 确实看似更安全的替代方案。如果有更多研究量化这些好处,那就太好了。这是因为,要让公司支付将所有关键 C/C++ 代码转换为更安全语言的成本,量化好处将有助于说服。这将是一个漫长的加强过程,但非常值得。
理解我们的软件供应链并加强它是至关重要的,但持续监控新出现的薄弱环节仍然是必不可少的。监控需要是一个主动的过程,所以你可以在任何时间识别出是否正在运行易受攻击的代码或启用了活跃攻击的代码。
显然,软件清单(SBOM)是监控的一个重要方面。但SBOM到底应该包含什么呢?SBOM肯定包括在软件中使用的软件包和版本的列表,但还需要什么呢?一个美国政府工作组模糊地定义了SBOM[19]——信息的数量和类型可能有所不同。这种模糊性是一个问题。
我之所以这么说,是因为我们需要防御的是软件漏洞和攻击。对于漏洞而言,我们绝对需要软件包和版本列表。而对于实际攻击,我可以说你可能需要知道编译该二进制文件的机器是什么,以防这台机器被入侵。但是,什么机器生成了SBOM文件呢?如果生成SBOM文件的机器被入侵了呢?如果SBOM文件是为了帮助应对攻击的,那么至少要非常小心如何安全生成它。如果SBOM文件并不用于应对攻击,那么我们只需要软件包和版本列表就可以了。我们也看到,描述供应链的复杂性是分形的,SBOM应该包含多少信息,到哪里止步,这需要进一步探讨。
我们应该准确界定SBOM的定义和应用范围,然后根据此确定SBOM应该和不应该包含的内容。但是现在我们对这些都没有什么了解。尽管如此,理解软件包含的代码还是非常重要的。
现在所有的Go二进制文件都包含编译到其中的所有Go代码包的列表,这可以看作是一种SBOM。Go没有提供发出或移除这些信息的构建选项,尽管有人提出过这样的要求。所以你可以放心,任何编译的Go二进制文件都包含这些信息。但是,这些信息不包含构建环境、构建者或生成源代码文件的工具等信息。
假定我们通过某种方式理解了软件供应链和组成内容,还需要已知漏洞的数据库来检查软件是否存在这些漏洞。
对Go而言,我们创建和维护了一个漏洞数据库。配合我们的工具,我们可以扫描程序中的已知漏洞。我们遇到的第一个问题是产生了太多误报。为了减少误报,我们的数据库不仅包含受影响的包和版本,还包含漏洞函数,如果这些函数没有被调用,就可以排除相关漏洞。通过源代码分析我们可以进一步减少误报。
此外,谷歌的开源漏洞项目(OSV)[20]的目标是构建一个包含所有开源漏洞的数据库,并给出精确的软件包和版本信息。Go安全团队和OSV团队一起定义了一种通用的漏洞格式,用于两个项目,后来我们又与其他生态系统合作帮助他们采用这一格式。现在,这一通用格式已经成为Go、Rust、Python和GitHub安全公告数据库等的本地漏洞格式。这个综合性数据库对任何想要使用它的人开放。
回到Go,我们有每个程序的SBOM和一个漏洞数据库,所以我们可以检查程序是否存在任何已知的漏洞。事实上,这基本上是我们所有人都同意SBOM的唯一用途。为此,我们编写了一个名为govulncheck
的工具。我们在使用govulncheck
时遇到的第一个问题是误报太多。例如,我的程序使用了Go包P中的代码,P中有两个函数F和V,F没有问题,V存在漏洞,但我的包只使用了F。但是在Go二进制文件中的SBOM并不十分精确,它只是说我使用了P包。所以根据SBOM,govulncheck
不得不报告这个潜在的漏洞,尽管我的程序实际上并不容易受到这个漏洞的攻击。
作为减少误报的第一步,Go 漏洞数据库不仅包括了软件包版本,还包括了软件包中易受攻击的特定函数名称。如果这些函数没有被调用,那么漏洞就不存在。因此,govulncheck
会解析 Go 二进制文件中的堆栈展开表,以识别哪些函数出现在二进制文件中。如果易受攻击的函数不在二进制文件中,那么就不存在漏洞。但是,这仍然可能导致误报,因为实际上无法访问的函数经常被链接到二进制文件中,正如这张幻灯片上展示的那样,这些都是误报。但从二进制文件来看,govulncheck
无法判断。
我们可以使用更复杂的静态分析来消除更多误报。当govulncheck
的输出与其他不太准确的工具(例如GitHub的Dependabot和其他与语言无关的工具(language neutral tools))进行比较时,报告误报非常重要。govulncheck
可以告诉你来自其他工具的关于严重漏洞的报告是否是真正的紧急漏洞。
如果没有人使用它,漏洞扫描就没有任何价值。因此,我们还将漏洞扫描集成到IDE中。这个屏幕截图显示了一个代码编辑会话,其中列出了依赖项,并且有一个波浪形下划线,表示一些依赖项存在问题。
用户将在运行govulncheck
后单击下拉菜单中的“运行目标检查”来查看它们是真正的漏洞还是误报。IDE报告添加了有关特定漏洞的详细信息,这是一个真正的积极因素。现在用户可以回到go.mod
并使用菜单选项来更新依赖项并解决漏洞。
在开发过程中越早提供此信息,就越容易让用户解决这些问题。当然,在开发结束并部署代码后,可能会发现新的漏洞,因此你还需要能够扫描已在生产中运行的代码中的漏洞。一种方法是扫描所有容器映像以查找你正在运行的容器。Google Cloud提供了工件分析API来执行此操作,并且它使用govulncheck
来扫描Go二进制文件。
这是可能的,因为每个Go二进制文件中的SBOM都包含了漏洞扫描所需的信息。然而,远未解决问题,还需要进行更多研究,例如如何避免多种误报并采用有效的方式来呈现信息。然后,我们还需要更好的系统来在日志发生时自动跟踪和部署更新。整个科技行业花了数周的时间来寻找和更新他们的所有系统,如果使用的是易受攻击的Log4j
版本,那么对Log4j
的下一个日志的响应根本就没有什么大不了的,因为我们还没有达到这个行业的标准。
这就是我对Google开源供应链安全的概述。我希望我已经让你了解我们的努力范围并突出了研究问题。在结束之前,你可能会发现你有兴趣探索这些问题。
我想进一步缩小范围,看看1972年3月美国过去半个世纪的开源供应链安全。当时,美国空军开始对霍尼韦尔Multics系统
进行审查,以了解其是否可以在安全环境中使用。1974年中期发布的报告得出结论,Multics
并不安全,但比同类系统更好。
该报告提出了在看似无害的系统调用中添加后门的可能性,他们将其称为Trap door
。如果传递了一个特定的、极不可能的参数,系统调用将允许读取或写入内核内存中的任意字节。即使是小的恶意更改也会完全破坏系统的安全性。报告探讨了如何进行这类更改的机制,并隐藏了这一选项,例如在软件分发期间进行更改。报告提到美国邮件和不安全的电话线路是拦截和修改源代码的方法。我特别感兴趣的是,以前有通过伪造的固件邮寄自定义补丁的想法。虽然这些攻击方法现在已过时,但类似的事情,如XcodeGhost攻击,仍然在发生。
另一个问题是,如果二进制文件被更改但源代码没有更改,这种trap door
将更难被检测。例如,攻击者可能更改上传到npm注册表的包文件,但保留源代码不变。这就是npm
正在探索使用sigstore
的原因之一,因为GitHub可以通过加密方式证明上传到npm的内容确实与源存储库匹配。报告还指出,如果系统是从源代码重新编译的,二进制trap door
"将丢失。因此,另一种方式是更改编译器以引入trap door
。
(如果)你已经阅读过Ken Thompson
在1983年CACM上发表的巡回获奖演讲《Reflections on Trusting Trust》
,你可能知道他是如何在Unix编译器中进行类似的更改的,以便在登录程序中插入后门,以接受任何帐户的特定密码。Ken甚至向我发送了实际的编译器后门代码,我对其进行了注释并发布了内容,它只包括99行代码和20行shell脚本。我鼓励大家阅读它。
现在我们已经到了2023年,自RTM互联网蠕虫[21]以来已经35年,自Ken的巡回奖演讲以来已有40年,自Multics安全调查以来已有50年。好消息是,我们知道如何防御编译器后门。可重现的构建使得可以将自己构建的编译器与使用不同编译器构建的相同源代码进行比较。如果它们一致,要么一切都很好,要么两个编译器都以完全相同的方式存在后门。因此,只要我们可以信任其中一个,我们就可以建立对另一个的信任。
但坏消息是,其他一切都是相同的,或者更糟。太多的关键生产代码是用C和C++编写的,使得意外漏洞变得太常见。空军报告担心后门可能会如何逃避仔细的源代码审查,但几乎我们所有人都在运行没有可用源代码的二进制系统,即使像Linux这样的开源操作系统,几乎没有人检查分布式二进制文件是否与源代码匹配。尽管如此,我们的安全状况可能比看起来要好。为什么会这样,将是一个很好的研究问题。
尽管如此,生活在一个需要复杂方法如编译器后门的世界可能会更好。但是,当技术行业想要提高安全性时,我们可以看到过去十年的巨大进步。大多数网络流量曾经是未加密和未经认证的,但感谢共同努力,现在大部分流量都是加密和认证的。这种进步给了我们希望,说明我们能够应对日益复杂的安全挑战。
当技术行业致力于提高安全性时,我想以一种充满希望的态度来结束这个话题。回想十年前,大多数网络流量都是未加密且未经验证的。但得益于我们共同的努力、良好的激励措施和优秀的工具,如今超过90%的典型用户网络浏览是通过HTTPS进行加密和验证的。十年前,密码泄露和账户盗用是常见的问题。尽管密码盗窃现在仍然频繁发生,但如果你启用了双因素认证,特别是使用安全密钥,你的账户在2023年会更加安全。
GitHub已经推出了对所有用户启用双因素认证的要求。事实证明,2023年并没有因此而出现大问题。大多数主要互联网公司都在支持无密码认证,这在不久前还是难以想象的。因此,我们知道,当业界有动力并愿意为安全改进付出代价时,是可以取得进步的。
谷歌也一直致力于此,我们通过赞助OpenSSF漏洞奖励计划[22],大力投资于开源安全和补丁奖励计划,提供安全补贴。其他公司也在大力投资于安全,更多的帮助总是受欢迎的。我们仍然需要研究哪些改变最有效,以及它们的原因,甚至是一些基本问题,如供应链安全的含义和应包含的内容。 (译者注:可参考 谷歌宣布专门针对开源软件的新漏洞奖励计划:最高可达 21.65 万元,涉及 Fuchsia / Golang 等项目[23])
美国关于供应链安全的最新行政命令,以及其他政府机构对供应链安全和安全编程语言的关注,还没有完全准确地定义“软件物料清单(SBOM)”。但感觉变革即将来临。我希望十年后回顾,会惊奇地发现事情变得如此美好。我希望大家能够提供帮助,为这个目标共同努力。非常感谢大家的关注。
参考资料
演讲内容: https://research.swtch.com/acmscored
[2]SCORED 23: https://dl.acm.org/doi/proceedings/10.1145/3605770
[3]go.dev/s/acmscored : https://research.swtch.com/acmscored.pdf
[4]XcodeGhost源码地址: https://github.com/XcodeGhostSource/XcodeGhost/
[5]相关报道: https://security.tencent.com/index.php/blog/msg/96
[6]苹果手机病毒感染事件——震惊业界的 XcodeGhost: https://www.bilibili.com/video/av606542281
[7]XcodeGhost风波: https://zh.wikipedia.org/wiki/XcodeGhost%E9%A3%8E%E6%B3%A2
[8]瞻博网络: https://baike.baidu.com/item/%E7%9E%BB%E5%8D%9A%E7%BD%91%E7%BB%9C/7655676
[9]SolarWinds: https://www.solarwinds.com/zh/network-management-software
[10]专访SolarWinds:遭受黑客攻击 给一家软件公司带来了什么: https://baijiahao.baidu.com/s?id=1734029482552693683&wfr=spider&for=pc
[11]篡改 npm 包盗取比特币始末: https://zhuanlan.zhihu.com/p/602836521
[12]谷歌安全研究员直呼复杂 | iMessage 零点击漏洞利用细节公开: https://zhuanlan.zhihu.com/p/448126689
[13]1张GIF图片即可黑进iPhone!谷歌团队叹:最复杂的漏洞之一!: https://baijiahao.baidu.com/s?id=1719939280520469316&wfr=spider&for=pc
[14]Kubernetes所依赖的来自200个模块的3000个包: https://deps.dev/go/k8s.io%2Fkubernetes/v1.28.4/dependencies/graph
[15]不同版本的Kubernetes依赖关系: https://deps.dev/go/k8s.io%2Fkubernetes/v1.28.4/compare?v2=v1.29.0-rc.0
[16]sigstore: https://www.sigstore.dev/
[17]SLSA的标准: https://slsa.dev/spec/v1.0/levels
[18]罗伯特·T·莫里斯: https://zh.wikipedia.org/wiki/%E7%BD%97%E4%BC%AF%E7%89%B9%C2%B7%E6%B3%B0%E6%BD%98%C2%B7%E8%8E%AB%E9%87%8C%E6%96%AF
[19]模糊地定义了SBOM: https://www.ntia.gov/sites/default/files/publications/ntia_sbom_framing_2nd_edition_20211021_0.pdf
[20]开源漏洞项目(OSV): https://osv.dev/
[21]RTM互联网蠕虫: https://baijiahao.baidu.com/s?id=1650049532296331711
[22]OpenSSF漏洞奖励计划: https://openssf.org/
[23]谷歌宣布专门针对开源软件的新漏洞奖励计划:最高可达 21.65 万元,涉及 Fuchsia / Golang 等项目: https://www.ithome.com/0/638/186.htm
本文由 mdnice 多平台发布