“C、C++ 不安全,新应用开发时就别用了,旧应用应该采取迁移行动”,近日,美国白宫国家网络主任办公室 (ONCD)在一份主题为《回到基础构件:通往安全软件之路》的 19 页 PDF 报告中强烈呼吁道。
其直言,C 和 C++ 这几种编程语言既缺乏与内存安全相关的特性,又在关键系统中大量使用,可能会带来极大的安全风险,希望开发者抓紧使用“内存安全编程语言”。
这是继美国国家安全局、网络安全和基础设施局 (CISA)等之后,又一政府机构发起呼吁,而且这一次直接与“保护国家安全”挂钩。根据报告指出,该建议是美国总统拜登网络安全战略的一部分,是“确保网络空间基石安全”的举措。
ONCD 呼吁:用内存安全的语言、让软件变得可测量
这份报告指出,“软件和硬件产品的用户始终被置于对网络紧急情况作出反应时立于站不住脚的位置。在多个危机的基础上作出反应往往会使他们陷入困境,而那些在第一线确保系统安全的国家不应承担这一负担的全部重量。”
所以,ONCD 要求各大公司、工程师、开发者从两个维度切入:
从软硬件方面减少内存安全漏洞的存在,如采用内存安全的编程语言和内存安全的硬件;
为了建立更好的网络安全质量度量,研究界可以解决软件可测量性这一困难而复杂的研究问题。
最终减少恶意行为者可以攻击的攻击面。
一提不安全的语言,必定被点名的 C、C++
内存安全是指防止与内存访问相关的错误和漏洞,其中包括缓冲区溢出和悬空指针等问题。这类问题可能导致程序崩溃、未定义的行为,甚至是安全漏洞,被恶意利用。
这些内存安全漏洞主要分为两类:空间和时间。
空间内存安全问题是由于在为内存中的变量和对象设定的“正确”边界之外进行执行内存访问造成的。
时间内存安全问题源于在时间或状态之外访问内存,例如在对象被释放后访问对象数据,或内存访问意外交错时,就会出现问题。
在过去几十年里,行业中发生的许多重大网络安全漏洞都是由内存安全漏洞促成的,包括 1988 年的 Morris Worm、2003 年的 Slammer Worm 拒绝服务攻击、2014 年的 Heartbleed 漏洞和 2023 年的 BLASTPASS 漏洞链。
聚焦到企业维度,此前我们也曾报道过一些关键数字:
2019 年微软安全工程师透露,从 2006 到 2018 年,微软每年 CVE 的漏洞中约 70% 是内存安全问题;
2020 年,在 Google Chromium 项目发现的漏洞中,约 70% 严重性安全错误是内存不安全问题(即 C/C++ 指针错误);
根据 Google Project Zero 团队的分析,2021 年有 67% 的零日漏洞是内存安全漏洞;
...
“由于许多网络安全问题始于一行代码,解决这些问题的最有效方法之一是检查程序设计语言本身”,ONCD 说道。
至于哪些是不安全的语言,ONCD 发布的报告中直接引用一些专家的观点——“专家们已经确定了一些编程语言,它们既缺乏与内存安全相关的特性,又在关键系统中具有高扩散性,例如 C 和 C++。”
无论是此前 CISA,还是今天的 ONCD,一提到内存不安全的编程语言,C、C++ 总是“榜上有名”,至于其中原因,主要还是和这些语言的功能特性有关:
C、C++ 支持指针,这意味着程序员可以直接访问和修改内存地址。虽然这种灵活性使得一些底层操作更容易,但也增加了因为误用指针而导致的内存安全问题的风险,比如野指针、内存泄漏和越界访问。
在 C 和 C++ 中,开发者需要手动分配和释放内存。这意味着程序员负责确保适当的内存分配和释放,而出现错误可能导致内存泄漏或释放后的悬挂指针问题。
C 和 C++中的数组和指针没有边界检查。最终可能发生数组越界访问的错误,从而导致程序崩溃或者未定义的行为。
缺乏自动垃圾回收: 相对于其他一些现代编程语言,C 和 C++ 不提供自动垃圾回收机制。这意味着程序员需要手动管理内存,容易出现错误。
由于这些特性,一些组织默认将 C、C++ 归为不安全的语言。
NSA 主推的七大安全语言:Java、Rust、C#...
有趣的是,报告并没有建议用一种特定的语言来代替它们。ONCD 倒是直接推荐了自己的兄弟单位,让大家去看看美国国家安全局(NSA)此前发布的网络安全信息表,并表示,“有几十种内存安全的编程语言可以使用。虽然在一些特殊情况下,使用内存安全语言可能不可行。但是在大多数情况下,使用内存安全的程序设计语言是显著改善软件安全性的最有效方法。”
而根据 NSA 的建议,内存安全编程语言有:
Rust
Go
C#
Java
Swift
JavaScript
Ruby
在衡量编程语言受欢迎程度的 TIOBE 指数中,NSA 推荐这些安全的编程语言:C# 排在第五位,Java 排在第四位,JavaScript 排在第六位,Go 排在第八位。而 Swift(16 位)和各大厂都在推荐的 Rust(18 位)、Ruby(20 位)排名稍微靠后。
从流行度上来看,这 7 种语言中只有 4 种使用率比较高,而其中热度最高的 Java,之所以被认为是内存安全语言的一部分原因是它在运行时具有强大的错误检测机制。Java 虚拟机(JVM)会在运行时检查数组边界,防止缓冲区溢出。此外,Java 中的垃圾回收机制有助于防止内存泄漏。这种自动化的错误检测和内存管理机制有助于减少程序员犯错的机会。
对此,ONCD 也建议道,“对于新产品,选择构建内存安全程序设计语言是一个早期的架构决策,可以提供显着的安全优势。对于现有的代码库来说,完全重写代码更具有挑战性,但可以通过混合方法采用内存安全编程语言。例如,软件开发人员可以根据风险标准识别关键功能或库,并优先考虑重写这些功能或库的工作。”
硬件也要用上内存安全的语言
除了在软件上要用安全语言之外,ONCD 认为硬件上也必须用上。
在报告中,ONCD 还以“阿波罗13号登月失败”为例:
在 1970 年 4 月,阿波罗 13 号上的一次爆炸打乱了它的登月计划。
宇航员航行两天后,一根暴露在外的电线引燃了一场大火,导致有一个液氧罐发生了爆炸。宇航员生存的唯一希望就是火箭科学家们做出巧妙而快速的反应。
运用物理定律和数学规则,火箭科学家们计算出登月舱燃烧的发动机,给出的建议是,宇航员们必须继续前进,如果飞船靠近月球就有可能借助月球引力返航,最终成功地将阿波罗 13 号送上返回地球的轨道。
ONCD 称,五十多年过去了,航空航天工程师和决策者都没有把太空安全的未来听天由命。在很大程度上,由于现代计算和软件工程的技术进步,数字自动化已经将人为错误的风险降到了最低。
不过,太空生态系统也难免存在内存安全漏洞,但太空系统在语言使用方面存在一些限制。
第一,语言必须允许代码接近内核,这样才能与软件和硬件紧密交互;
第二,语言必须支持确定性,这样输出的时序才能保持一致;
第三,语言必须没有或无法覆盖“垃圾回收器”,该功能可自动回收计算机程序分配的不再使用的内存。
这些要求有助于确保太空系统所必需的可靠和可预测的结果。
ONCD 表示,“内存安全和内存不安全的编程语言都符合这些要求。目前,同时满足这三个属性的最广泛使用的语言是 C 和 C++,它们都不是内存安全的编程语言。Rust 是内存安全程序设计语言的一个例子,具有上述三个必要的属性,但尚未在太空系统中得到证明。需要在开发工具链、员工教育和实地案例研究方面取得进一步进展,才能证明在这些用例中存储安全语言的可行性。”
此外,该报告还呼吁业界要使用硬件芯片支持内存保护,其实行业中已有人展开行动,如美国 SRI International 和剑桥大学联合研究项目——硬件增强型 RISC 指令的能力(Capability Hardware Enhanced RISC Instructions,简称 CHERI),为现有的芯片架构增加了新的功能;Arm 公司也探讨了其实验性 Morello Program 及 CHERI 架构实现原理,希望借此解决系统攻击中常被利用的一系列内存访问漏洞。
同时,ONCD 认为软件的可测量性也非常重要。不过与物理工程产品不同,大多数软件缺乏统一的结构或组成。这种设计和架构的不同性导致建立通用的衡量指标异常复杂化。
正因此,ONCD 也无法给出具体的建议,只是希望未来更多的大型组织、科技公司以及不同的政府部门协力参与进来。
盲目弃用并不可取,有人认为:“C++ 受到了不公正的对待”
值得注意的是,不同于其他部门,ONCD 在早些时候就对这些提议还征集了一波业界的一些看法。据 DevClass 报告,各大科技公司、基金会也都纷纷表态:
Rust 基金会呼吁“要求公共资助机构及其承包商默认使用 Rust 等内存安全编程语言”。
微软将重点放在了软件供应链以及对开放源代码缺乏足够的投资等维度上。
IBM 表示,重写软件可能过于昂贵,并提倡“保护现有软件免受内存安全漏洞影响 ”的方法。
Google 表示,同意政府倡导的“向内存安全语言和框架过渡”。
AWS 则“完全支持使用内存安全语言编写新项目的做法”,但也表示这“只是提高开源软件安全性的整体努力中的一个小因素”,并强调有些开发人员可能会直接禁用掉 Rust 内存安全的功能,同时逻辑错误可能会成为“比内存安全更大的安全问题”。
当然,除了支持声音之外,也有人认为 C++ 语言遭受了冤屈。
一位自称是“在 ISO C++(ISO/IEC SC22/WG21)中拥有数十年经验的 C++ 资深成员”发表了一篇论文做出回应。
他们的论文指出,“内存安全只是安全性中很小的一部分”,并且“C++ 的优势在于它有正式、完整规范的内存模型以及活跃的用户和实施者社区”。
相比之下,他们认为,一些被视为安全的语言却缺乏正式的规范。“C++ 受到了不公平对待。”
他们表示,“对 C++ 的许多批评都是基于用传统语言甚至 C 语言编写的代码,这些代码没有使用旨在提高类型和资源安全性的现代设施”。
同时,该团队也认为,还有很多其他方式会导致编程错误,包括逻辑错误、资源泄露、并发错误、类型错误、定时错误、终止错误等等。他们赞成加强对 C++ 程序员的教育,“从一开始学习阶段就解决安全问题”。
现实来看,作为 TIOBE 榜单上的热门语言,类 UNIX 编程都在用 C,而系统级编程、游戏开发、乃至人工智能和机器学习的底层实现中,都离不开 C++ 语言。短时间内在各个应用程序上谈用内存安全语言替代,似乎并不现实。
来源:
https://devclass.com/2024/02/27/white-house-demands-memory-safe-programming-languages-but-iso-c-group-says-its-only-part-of-solution/
https://www.whitehouse.gov/oncd/briefing-room/2024/02/26/memory-safety-statements-of-support/
https://www.whitehouse.gov/wp-content/uploads/2024/02/Final-ONCD-Technical-Report.pdf