关于C和C++的安全性,科学能告诉我们什么

2020-05-28 19:39:12

在编程语言领域,没有太多非常有力的实证结果。这很可能是因为有大量的变量需要控制,而研究人员可以获得的大多数研究对象都是CS本科生。然而,我最近发现了一个在众多代码库中重复的结果,据我所知,这使其成为该领域最可靠的发现之一:

如果您有一个非常大(数百万行代码)的代码库,并且是用内存不安全的编程语言(如C或C++)编写的,那么您可以预期至少65%的安全漏洞是由内存不安全引起的。

Android(引用):“我们的数据显示,在Chrome和Android中,释放后使用、双重释放和堆缓冲区溢出等问题通常构成了超过65%的High&;Critical安全漏洞。”

Android的蓝牙和媒体组件(CITE):“释放后使用(UAF)、整数溢出和越界(OOB)读/写构成了90%的漏洞,其中OOB最为常见。”

iOS和MacOS(引用):“纵观整个iOS12,苹果已经修复了261个CVE,其中173个是内存不安全。这占所有漏洞的66.3%。“。“在整个莫哈韦,苹果公司已经修复了298个CVE,其中213个是内存不安全的。这占所有漏洞的71.5%。“。

Chrome(引用):“Chromium项目发现,我们大约70%的严重安全漏洞是内存安全问题。”

微软(Cite):“微软每年分配给CVE的漏洞中,约有70%仍然是内存安全问题。”

Firefox的CSS子系统(CITE):“如果我们有一台时光机,可以从一开始就用Rust编写这个组件,51个(73.9%)的错误是不可能的。”

Ubuntu的Linux内核(引用):“在过去六个月Ubuntu对Linux内核进行安全更新的背后,65%的CVE存在内存不安全问题。”

这些数字与我们在0天内发现的被剥削的情况是一致的。

这一观察结果已经在许多非常大的代码库中重现,这些代码库由不同的公司构建,开始于不同的时间点,并使用不同的开发方法。我不知道有什么反例。它们的一个共同点是都是用内存不安全的编程语言编写的:C或C++。

基于这些证据,我准备得出结论,使用内存不安全的编程语言不利于安全性。这将是一个令人兴奋的结果!经验证明,改进软件的技术干预是罕见的,而内存不安全漏洞是我们知道的唯一一种可以通过选择内存安全语言来完全消除的漏洞。然而,我们作为理性经验主义者来处理这个问题,看看证据是否真的值得得出内存不安全的编程语言对安全性有害的结论,这是至关重要的。

有一些漏洞只存在于内存安全的语言中(例如,在不受信任的输入上使用eval;eval往往只存在于非常高级的语言中,它们都是内存安全的)。

因此,第一个集合包含这些类型代码库中至少65%的漏洞,从逻辑上讲,第二个集合必须包含35%的漏洞。因此,如果我们将编程语言更改为内存安全的语言,我们至少可以消除65%的漏洞。但是其他几组的大小有变化吗?

我假设第二个集合保持相同的大小:没有理由或证据认为将C++移植到内存安全的语言会导致额外的SQL注入。

我们的第三组是特定于内存安全语言的漏洞。根据我的经验,eval在生产代码中的实际使用非常罕见,但是它的近亲“不安全反序列化”确实在现实世界中发生。为了调查其频率,我研究了Java在Android上的不安全反序列化。根据我回顾的研究,Android作为一个整体似乎有十几个这样的系统。基本上每个月它都有比这个类的漏洞更多的内存不安全问题。所以我相信这一类比我们的第一套要小几个数量级。

总之,经验研究支持这样一个命题,即对这些项目使用内存安全的编程语言将导致漏洞总数的显著减少。

就像所有的经验性声明一样,随着我们获得更多的数据,这一点可能会被修正。你可以通过以下两种方式证明我是错误的:a)找到用内存编写的非常大的代码库-不安全的语言,经过大量的第一方和第三方安全研究,导致内存不安全的漏洞的比例要低得多;或者b)找到具有内存安全特定漏洞的代码库,其规模相当(每个版本修复数十个)。在获得证据之前,不要费心于假设某人可以编写1000万行代码