当前位置: 欣欣网 > 码农

「剑指 C/C++」,美国 CISA 等机构再发警告:Linux 中 95% 没用内存安全代码!

2024-07-03码农

整理 | 苏宓

出品 | CSDN(ID:CSDNnews)

如同微软想尽办法让消费者尽可能地升级到最新的 Windows 11 系统一样,美国安全机构无时无刻也不在发力,希望广大程序员可以使用 Rust 等更安全的语言替代掉无法自动防止内存错误的语言如 C、C++ 等。

Image Creator from Microsoft Designer

美国安全机构再发 22 页报告,「剑指」开源软件

近日,美国网络安全部门(CISA)联合美国联邦调查局(FBI)、澳大利亚信号局(ASD)、澳大利亚网络安全中心(ACSC)和加拿大网络安全中心(CCCS)共五大机构又发布了一份 22 页的调查报告——【探索关键开源项目中的内存安全】,总结了他们对 OSS 中使用内存不安全代码的调查结果。

以 GitHub 代码托管平台和 OpenSSF(开源安全基金会)为调研平台,CISA 这些机构此番分析了全球 172 个关键开源项目, 包含了 Chromium、Linux、 MySQL Server、TensorFlow、JDK、Node、KVM、GCC 等主流的浏览器、操作系统、数据库、框架项目。

同时,CISA 等机构使用的内存不安全语言定义如下,覆盖 Assembly、C、C++、Cython 等内存不安全编程语言。

根据调查,其得出以下一些结论:

  • 172 个项目中有 52% 是使用 C、C++ 和其他所谓「内存不安全」的语言编写的。

  • 所有项目的总代码行(LoC)中有 55% 是用内存不安全的语言编写的。

  • 最主流的一些项目在很大程度上是用内存不安全的编程语言编写的。 在按 LoC 总数计算的十大项目中,每个项目使用内存不安全 LoC 的比例都超过了 26%。在这十个项目中,使用内存不安全语言的比例中位数为 62.5%,十个项目中有四个项目的比例超过 94%。

  • 对用内存安全语言编写的三个项目进行的依赖性分析表明,每个项目都依赖于用内存不安全语言编写的其他组件。

  • 具体来看,根据调研数据显示,总共有 26023 KLoC(千行代码)的 Linux 项目中,约 95% 的代码行都是内存不安全的;对于 MySQL Server,这一比例为 84%;对于 TensorFlow,这个数字是 64%;对于 Zephyr,这个数字是 84%;对于 Chromium,这个数字是 51%。

    平均而言,10 个最大的开源项目中,总代码行中有 26% 是内存不安全的代码。 即使是用内存安全语言编写的项目也因依赖不安全的组件而面临风险。

    与此同时,报告称, 「我们确定所分析的大多数关键开源项目,甚至那些用内存安全语言编写的项目,都可能包含内存安全漏洞。 这可能是由于直接使用内存不安全的语言或外部依赖使用内存不安全性的语言的项目造成的。 此外, 禁用内存安全的低级功能需求可能会在以其他内存安全语言编写的代码中造成内存安全漏洞 。这些限制凸显了继续认真使用内存安全编程语言、安全编码实践和安全测试的必要性。」


    多份报告相继发布:呼吁弃用 C/C++ 等内存不安全的编程语言

    事实上,近几年来,业界愈发关注内存安全问题。据安全组织 Security Planner 于 2022 年 10 月发布的一份【消费者报告】 (https://advocacy.consumerreports.org/wp-content/uploads/2023/01/Memory-Safety-Convening-Report.pdf) 指出,「大约 60%-70% 的浏览器和内核漏洞——以及在 C/C++ 代码库中发现的安全漏洞——是由于内存不安全导致的。」 该报告还引用了一段关于使用内存安全语言代替内存不安全语言的安全成本和收益的有趣讨论。

    自此,使用更加安全的内存语言便成为美国多个政府机构引导的主要方向,这也是其连发多个文件、呼吁项目迁移到更安全编程语言的原因:

  • 2022 年 11 月, (NSA)发布了关于保护软件开发者和运营商免受内存安全问题影响的指南, 鼓励多个组织将编程语言从 C/C++ 转为使用内存安全的语言,如 C#、Rust、Go、Java、Ruby 和 Swift,主要原因是这样可以帮助软件开发者和使用者预防并缓解软件内存安全问题,这些问题占可利用漏洞的很大一部分;

  • 2023 年 3 月发布的【2023年国家网络安全战略】和2023年7月发布的相应实施计划均讨论了投资于内存安全并与开源社区合作的内容。【国家网络安全战略实施计划】的第4.1.2项倡议「促进开源软件安全和内存安全编程语言的采用」指示建立「开源软件安全倡议(OS3I)以推动内存安全编程语言和开源软件安全的采用。」 同一文件中的第4.2.1项倡议「加速内存安全编程语言的成熟、采用和安全性」也呼吁投资于内存安全编程语言,并寻求新成立的OS3I的参与。

  • 2023 年 12 月,美国网络安全和基础设施局 (CISA)也开始联合 NSA、美国联邦调查局 (FBI) 以及澳大利亚、加拿大、英国和新西兰的网络安全机构发布了一份 23 页的【 】,这份文件指出,内存安全漏洞是最常见的软件漏洞类型之一,并给软件制造商和消费者带来修复、及时响应和其他努力相关的巨大成本。建议软件制造商创建内存安全路线图,包括解决外部依赖(通常包括开放源代码软件)中的内存安全的计划。

  • 2024 年 2 月,美国白宫国家网络主任办公室 (ONCD)在一份主题为【 】的 19 页 PDF 报告中强烈呼吁道,「C、C++ 不安全,新应用开发时就别用了,旧应用应该采取迁移行动」。

  • 时下,CISA 联合其他国际安全组织发布的报告直接揭晓了一些主流开源项目中使用的不安全内存语言编写的代码行数,其也遵循了以上战略路线,希望引发开发者、企业的注意,有效避免内存安全错误。

    各大科技公司已经开始「重写」、「迁移」等行动

    这份报告也再次强调,像 C 和 C++ 这样的内存不安全编程语言允许程序员对代码中的内存相关功能进行更直接的控制,这通常会导致非常常见的应用程序安全问题, 例如缓冲区溢出、使用未初始化内存、类型混淆和使用后释放漏洞 。这类缺陷在现代应用软件的所有漏洞中占了很大比例。

    相比之下,内存安全语言(最常见包括 Rust、Python、Java 和 Go)提供了如内置运行时和编译时检查等保护措施,以减轻常见的内存相关错误。

    最近几年,在政策引导下,不少大厂、项目确实开始发力使用内存安全的编程语言:

  • 2021 年,由 AWS、华为、谷歌、微软和 Mozilla 等创始成员支持, Rust 基金会成立

  • Linux 是从 2022 年 12 月开始合并 Rust 代码。Linux 之父 Linus Torvalds 在去年 12 月出席 Open Source Summit Japan 2023 上透露 :「Rust 一直在成长,但我们还没有内核的任何部分真正依赖 Rust。对我来说,Rust 是技术上有意义的事情之一,但对我个人来说,更重要的是,作为内核和开发人员,我们不能停滞不前。」

    尽管如此,Torvalds 继续说道:「Rust 还没有真正成为下一个伟大的事物。但我认为,在明年,我们将开始集成驱动程序,甚至一些主要的子系统也将开始积极使用 Rust。因此,要让它成为内核的重要组成部分,还需要数年时间。但它肯定会成为内核的一部分。」

  • 互联网安全研究小组(ISRG)发起的 Prossimo 项目,它的目标是通过使用具有内存安全属性的语言来解决 C 和 C++ 代码中的内存安全问题,从而改善互联网敏感的软件基础设施,而这种基础设施的代表就是 Linux 内核。参与 Prossimo 项目的开发者们一直在用 Rust 重写关键的开源库,以减少遗留代码中内存缺陷的风险。就在本周,Let’s Encrypt 表示它已经部署了 ntpd-rs,这是 Prossimo 用 Rust 重写的网络时间协议(NTP)守护进程。

  • 同时,在这一趋势下,Google 和微软都开始向内存安全语言迈进,最初是用于新项目,最近则用于应用程序重写。

    不久前,Google 的工程总监 Lars Bergstrom 在伦敦的 Rust Nation UK 大会 上分享了 Google 将 Go 或 C++ 编写的项目迁移到 Rust 语言的经验。他表示,「使用 Rust 的开发团队相比于使用 C++ 的团队,在工作效率上大约高出两倍。」

    对于另一大科技公司微软,此前其 Windows 操作系统安全总监 David 「dwizzle」 Weston 透露,微软正在用 Rust 编程语言重写核心 Windows 库。

    迁移之路,任重而道远

    然而,鉴于将代码库完全用内存安全语言进行重写这一任务过于复杂、成本高昂,因此仅想要通过政策的引导就能实现业界做出大规模的改变,显然不太现实。

    更何况 为了应对内存安全编程语言的挑战,争议之中的编程语言如 C++ 社区也正在尝试通过 C++ 配置文件使开发者能够编写更安全的代码,这些配置文件在编译时提供安全保证。

    针对这一点,CISA 在报告中也指出, 还有很多工作需要完成。

    「在性能和资源约束的地方,我们预计内存不安全的语言会继续使用,包括操作系统内核和驱动程序、密码学和网络,尤其是嵌入式应用程序」,CISA 报告指出,「同时,即使在使用内存安全语言时,开发人员也可能禁用内存安全特性。AWS 在对‘开放源码软件安全信息请求’的回应中,建议‘使用像 Rust 这样的内存安全语言’编写新代码,但要注意并非所有名义上使用内存安全语言写成的代码实际上都是内存安全的...开发人员禁用使 Rust 内存安全的编译器特性是容易的,而且相当普遍。」

    因此,CISA 等组织也没有特别好的办法,只是表示,「我们鼓励其他人在此分析的基础上进一步扩大我们对开源软件内存不安全风险的集体理解,评估降低这种风险的方法(例如用内存安全语言有针对性地重写关键组件),并继续努力推动软件制造商采取降低风险的行动。」

    业界看法

    对此,来自 Synopsys 软件完整性小组技术经理 Gunnar Braun 表示, 「该报告及其之前的‘内存安全路线图指南’将这个问题提交给了公司 C 级高管——这是理所应当的。软件安全与保障不再是纯粹的技术问题。」

    Braun 表示,许多开源程序运行在资源受限的嵌入式系统中。 如果无法改变编程语言,那么使用静态代码分析和模糊测试工具来降低内存安全风险就显得尤为重要。

    「一些内存安全语言,例如 Rust 或 Go,已经进入嵌入式系统,因此我乐观地认为 C/C++ 终有一天会被大量取代——但不是今天,也不是明天,」他说道。

    OpenSSF 总经理 Omkhar Arasaratnam 认为,「内存安全问题并不是开源或闭源软件特有的问题。它是所有现代软件的普遍问题。 如今有许多内存安全的语言,比如 JavaScript、Python 和 Java,但软件工程师经常使用内存不安全的旧语言,比如 C/C++,以实现性能或低级硬件访问。 此外,尽管 Rust 近年来已成为低级系统编程中 C/C++ 的可行替代品,但有许多嵌入式系统和安全关键型应用程序并不适合 Rust。」

    他补充道, 「虽然用内存不安全的语言编写内存安全的代码是完全有可能的,但 25 年的 CVE 告诉我们,这种情况极不可能发生, 这并不是说人们是糟糕的程序员,而是用内存不安全的语言编写内存安全的代码非常困难

    在部分开发者看来,「这的确 很好地提醒了我们,非内存安全的遗留语言不会消失。确实如此!虽然最好不要用低级语言编写某些项目,但它们已经存在,重写是一个巨大的工程,可能会引入其他逻辑错误。更好的开发方式是使用工具,并 实际使用它们来修复一些关键的现有代码。」

    也有人认为:

    内存安全语言虽然被设计来减少内存泄漏的风险,但实际上仍然可能发生内存泄漏。有时候,像 C 语言(或 C++)往往会出现一些简单的问题,但这些问题相对容易解决。当然,你仍然需要一个良好的测试套件来确保代码质量,但一旦通过了类似 valgrind 的工具进行了内存清理,保持代码在可控的范围内并处理新的 Bug 相对较容易。

    尽管不太熟悉 Rust,但 Java 程序员曾经在使用他们能找到的库时遇到过问题。他们可能没有充分了解自己使用的具体库,因此可能会出现严重的内存泄漏问题。虽然他们的测试用例可能在他们自己的机器上运行正常,但对于企业级软件来说,这些问题可能会倍增,过多的内存使用仍然可能导致系统崩溃。」

    在 AI 时代下,甚至有人建议,「与其用内存安全的编程语言重写程序,倒不如可以让 AI 帮忙捕捉一些安全漏洞。」

    对此,你如何看待美国 CISA 等机构发布的报告 编程语言安全性是否可以直接提升程序安全性?欢迎留言分享你的见解。

    参考:

    https://www.theregister.com/2024/06/28/cisa_open_source/

    https://www.darkreading.com/application-security/cisa-memory-unsafe-code-open-source-projects

    https://www.cisa.gov/sites/default/files/2024-06/joint-guidance-exploring-memory-safety-in-critical-open-source-projects-508c.pdf

    推荐阅读:

    由 CSDN 和 Boolan 联合主办的「2024 全球软件研发技术大会(SDCon)」将于 7 月 4 -5 日在北京威斯汀酒店举行。

    由世界著名软件架构大师、云原生和微服务领域技术先驱 Chris Richardson 和 MIT 计算机与 AI 实验室(CSAIL)副主任,ACM Fellow Daniel Jackson 领衔,BAT、微软、字节跳动、小米等技术专家将齐聚一堂,共同探讨软件开发的最前沿趋势与技术实践。