"NSA建议企业考虑在可能的情况下,从很少或没有提供固有内存保护的编程语言(如C/C++)转向内存安全语言。内存安全语言的一些例子是C#、Go、Java、Ruby和Swift,"NSA说。
该机构引用了Google和微软最近的研究,他们在Chrome和Windows中分别有70%的安全问题与内存有关,其中许多是使用C和C++的结果,这两种语言更容易出现基于内存的漏洞。
"NSA在"软件内存安全"网络安全信息表中指出:"恶意的网络行为者可以利用这些漏洞进行远程代码执行或其他不利影响,这往往可以损害一个设备,成为大规模网络入侵的第一步。常用的语言,如C和C++,在内存管理方面提供了很大的自由度和灵活性,同时严重依赖程序员对内存引用进行必要的检查。"
因此,该机构建议尽可能使用内存安全语言,无论是应用开发还是系统编程。
虽然大多数信息安全专家都熟悉关于内存安全语言的辩论,但也许不是所有的开发人员都熟悉。不过,也许他们应该熟悉,因为这是一个几十年前就存在的问题,正如Java创建者James Gosling最近在讨论如何以及为什么创建Java时指出的。
如果有的话,NSA的文件为开发者提供了一个清晰的、通俗的解释,说明了向内存安全语言转变背后的技术原因。在内存安全方面讨论最多的语言可能是Rust,它是作为C和C++的"替代品"的主要候选。
Linux内核最近引入了Rust作为C语言的第二种语言,继Android开源项目之后。这些项目不会取代旧的C/C++代码,但对于新的代码会优先考虑Rust。另外,微软Azure首席技术官Mark Russinovich最近呼吁所有开发人员在所有新项目中使用Rust而不是C和C++。
"通过利用这些类型的内存问题,恶意行为者--他们不受软件使用的正常预期约束--可能会发现他们可以在程序中输入不寻常的输入,导致内存以意想不到的方式被访问、写入、分配或删除,"NSA解释说。
但是--正如专家们在关于Rust和C/C++的辩论中所指出的那样--NSA警告说,仅仅使用一种内存安全语言并不能默认排除将内存错误引入软件。此外,语言通常允许使用不是用内存安全语言编写的库。
"即使使用内存安全语言,内存管理也不完全是内存安全的。大多数内存安全语言承认,软件有时需要执行不安全的内存管理功能来完成某些任务。因此,有一些类或函数被认为是非内存安全的,并允许程序员执行可能不安全的内存管理任务,"NSA说。
"一些语言要求任何内存不安全的东西都要明确注释为内存不安全,以使程序员和程序的任何审查人员意识到它是不安全的。内存安全语言也可以使用以非内存安全语言编写的库,因此可以包含不安全的内存功能。尽管这些包含内存不安全机制的方式颠覆了固有的内存安全,但它们有助于定位可能存在内存问题的地方,允许对这些代码部分进行额外的审查。"
NSA指出,向一些内存安全语言的转化可能要付出性能上的代价,这需要开发人员学习一种新的语言。它还指出,开发人员可以采取一些措施来加固非内存安全语言。例如,Google的Chrome团队正在探索多种方法来加固C++,但这些方法也会带来性能开销。在可预见的未来,C++将继续留在Chrome的代码库中。
NSA建议进行静态和动态应用程序安全测试,以发现内存问题。它还建议探索内存加固方法,如控制流保护(CFG),它将对代码的执行位置进行限制。同样,建议使用地址空间布局随机化(ASLR)和数据执行预防(DEP)。