为什么对安全至关重要的软件是用不安全的语言编写的?

信息安全 编程 图书馆
2021-09-03 20:42:53

这可能是一个愚蠢的问题,但是...

为什么用 C 和 C++ 等语言编写对安全至关重要的软件?我理解为什么嵌入式系统可能需要一种低级语言来充分利用有限的资源,但是用低级语言编写安全软件似乎很愚蠢。

我之所以问这个问题是因为每当我访问 debian.org 并查看最新的安全修复程序时,其中绝大多数都涉及内存安全问题,这些问题仅出现在 C 和 C++ 等不安全的语言中。例如,像 Java 那样糟糕的代表,我认为 OpenSSL 的 90% 的安全补丁将完全无用。如果使用更高级的语言,如 Scala 或 Lisp,我想它会更容易让事情变得安全。在最坏的情况下,弄乱你的数组会导致运行时错误。

使用 C/C++ 的原因是避免侧信道攻击吗?我可能会想象某个键的某些属性会干扰保守垃圾收集器(如 Boehm)的执行并导致计时攻击,但无论如何都没有更高级别的语言使用不安全的垃圾收集器。

4个回答

大多数软件都是用开发人员知道如何使用的语言编写的,对于与安全相关的软件,这并不是一件坏事——只要开发人员真正了解他选择的语言,直到细节,我可能会争辩说C 和 C++ 的情况并非如此(绝大多数认为自己了解 C 或 C++ 的开发人员实际上是错误的)。

在类 Unix 系统上,特别是 Linux(所有开源开发的重要部分都发生在这里),C 是“最”系统语言。Unix 对 C 非常友好(所有低级 API 都是基于 C 的,用 C 头文件描述;系统库是用 C 编写的,因此 C 编译器经过良好测试和良好集成)。这导致了一个基于 C 的大型生态系统,其中开发人员使用 C 是因为他们了解 C 并希望使用提供基于 C 的 API 的库。这具有很好的可移植性优势(例如,在 PowerPC 或 Mips 上运行 OpenSSL 没有问题——尝试使用 Java 来做这件事!)。

使用另一种语言会带来一些问题:缺乏运行时支持、较少的可移植性、假设缺乏性能......(“安全”语言可能是高效的,但一些广泛的实现要么很慢,因为它们使用没有JIT的解释器,要么将记忆猪;而且许多人只是认为这些语言天生就很慢,因为他们实际上并没有尝试过,而是用口号思考)。

这导致了我的结论:人们将 C 和 C++ 用于传统的安全关键软件。

(我写所有这些都是作为一个编写自己的 Java VM 以运行完全用 Java 编写的 SSL 服务器的人,在一个具有 16 MB RAM 的小型 50 MHz PowerPC 系统上——它是一个证书颁发机构,它可以同时为 70 个客户端提供服务. 所以当我说像 Java 这样的“安全”语言可以用于在低功耗系统上运行安全关键软件并具有良好的性能时,我是认真的。)

您可以用任何语言编写不安全的软件。C 和 C++ 可能很容易犯严重错误,尤其是对于没有经验的程序员...

...即使作为最有经验和最细心的程序员,您也无法控制高级语言复杂性中的安全问题。

使用 C 和 C++,您可以对代码中发生的事情进行大量控制。编译器可以相对简单,并且经常经过很好的审查。这意味着,您犯的任何错误都可能是您自己的错误。在高级语言中,您通常必须依赖 API 的安全性和所使用的语言功能,这会导致更复杂的系统更难审计。

安全关键错误所在的代码基础最终比高级语言更易于管理。

实际上,在某些情况下,必须使用此类语言才能确保安全,因为高级语言无法提供足够的硬件访问权限。例如,在不再需要加密密钥后从内存中擦除它们。或者确保多个代码路径的长度相同,因此需要相同的时间来防止侧通道攻击。

这是一个很好的问题。

如果您问此类软件的作者,大多数人会说性能。对于某些东西,比如 Linux 内核,这种性能是必不可少的。但是对于很多软件来说,性能并不那么重要,这使它成为一个糟糕的理由。想象一个速度慢 50% 的 Web 服务器,但从未出现过安全漏洞。很多用户会乐于以性能换取安全性。

使用托管语言并不能保证安全。考虑 Java 或 C#——它们是内存安全的;(除了 VM 错误)不可能有缓冲区溢出漏洞。但是它们可能存在注入漏洞、访问控制漏洞等。但是,这些漏洞更容易检测和预防。非内存安全语言(如 C/C++)的一个特别关注点是,在复杂的应用程序中检测细微的内存损坏缺陷非常困难。

如果我们从今天开始,我认为会有更多的软件使用托管语言编写。但我们从不从一张白纸开始,很多软件都是用 C 语言编写的。问题是,很多软件都掌握了安全的窍门。以 Apache 为例——如果你回溯十年左右,它会出现很多严重的问题,但最近的历史要好得多。有了这个记录,用另一种语言完全重写代码的动力就消失了。

请记住,虽然许多现成的软件是非托管的,但大多数定制软件(包括大量自定义 Web 应用程序)都是用托管语言编写的。

目前,软件安全性最差的地方是桌面,网络浏览器和插件是最严重的违规者。不幸的是,大多数 Web 浏览器缺陷都与沙盒语言(JavaScript、Java、Flash 等)相关,并且以托管语言为这些语言编写 VM 将对性能造成重大影响。

创建一套从头开始构建以确保安全的计算软件将是一个有趣的项目。我知道 OpenBSD 多年来一直在推动这一口号,但他们的方法似乎并不完全正确。如果其他人要承担这个责任,那么几乎所有事情都使用托管语言会很有意义。