事件背景:
美国网络安全与基础设施安全局 (CISA) 发布了一份名为 《the case for memory safe roadmaps》的文件,详细介绍了软件厂商应如何过渡到内存安全编程语言 (MSL),以消除内存安全漏洞。
CISA 认为,内存安全错误经常会造成重大损失,需要加以杜绝;因此敦促企业和技术领导者密切关注软件开发中的内存安全。而 C 和 C 等编程语言就是内存不安全编程语言的典范;它们可能导致内存不安全代码。
从该文件中的数据显示:微软约 70% 的 CVE 是内存安全漏洞(基于 2006-2018 年的 CVE),Mozilla 的 34 个关键 / 高危漏洞中有 32 个是内存安全漏洞。谷歌 Chromium 项目中所发现的漏洞,有约 70% 是内存安全漏洞;且 2021 年的零日漏洞中也有 67% 是内存安全漏洞。
因此他们建议放弃 C/C ,转而使用 C#、Go、Java、Python、Rust 和 Swift 等 “内存安全语言”。
那么从工程师的角度来看待该问题的影响:
美国网络安全与基础设施安全局(CISA)建议放弃C/C 来消除内存安全漏洞是有一定道理的。C/C 是一种低级编程语言,它们允许程序员直接管理内存,这也就意味着程序员需要手动处理内存分配和释放。由于这种手动管理可能会导致错误,例如内存泄漏、缓冲区溢出等,因此C/C 语言本身就存在一定的安全隐患。
CISA的建议并不是要完全放弃使用C/C ,而是强调在可能的情况下,应该优先考虑使用更安全的编程语言和技术。例如,使用高级语言和框架可以减少代码中潜在的安全漏洞。同时,对于必须使用C/C 的情况,应该采取一些最佳实践来减少潜在的安全风险,例如使用安全的库和函数、进行代码审查、进行安全测试等。
另外,从另一个角度来看,C/C 并不是唯一存在内存安全漏洞的语言。其他高级编程语言也可能存在类似的漏洞,因为这些语言也需要处理内存分配和释放。因此,即使放弃了C/C ,也不能完全消除内存安全漏洞。因此,关键在于采用适当的开发方法和安全策略,而不仅仅是选择哪种编程语言。
该建议是否会撼动C/C 的主导地位?
从一定程度上说,漂亮国的这个决议,有可能会对C/C 语言的主导地位产生一定的影响。 目前C/C 是在许多领域广泛使用的编程语言,包括操作系统、嵌入式系统、游戏、金融和医疗等。它们的灵活性和效率使得它们成为许多开发人员的首选。然而,由于C/C 语言在内存管理方面的灵活性,也使得它们容易出现内存安全漏洞,例如缓冲区溢出和释放后使用漏洞等问题。 漂亮国CISA的建议是改用像Rust这样的内存安全语言来消除这些漏洞。Rust是一种新兴的编程语言,特别注重内存安全和并发性,它的设计目标就是解决C/C 所面临的这些问题。 然而,尽管C/C 存在这些问题,但它们仍然具有强大的生态系统和广泛的应用。许多现有的项目和代码库依赖于C/C ,并且它们在某些领域的性能优势也是其他语言难以替代的。因此,尽管有建议改用其他语言,但C/C 的主导地位仍可能持续一段时间。 此外,对于一些需要高性能或与硬件紧密交互的项目,C/C 可能仍然是首选。例如,一些游戏引擎和嵌入式系统开发仍然主要使用C/C 。因此,尽管CISA的建议可能会对C/C 的主导地位产生一定的影响,但它们并不会完全取代C/C 。
作为C/C 程序员,避免引入内存安全漏洞的方法有很多。以下是一些建议:
- 使用安全的函数和工具:例如,使用
strcpy_s
和strcat_s
等安全函数,以防止缓冲区溢出。这些函数在执行操作时可以限制缓冲区的大小,从而防止了缓冲区溢出。 - 初始化变量:确保所有变量在使用之前都进行了正确的初始化。未初始化的变量可能会导致未定义的行为,从而引入内存安全漏洞。
- 检查指针:在使用指针之前,始终确保指针不是NULL。否则,可能会引发段错误。另外,也要确保在访问指针引用的内存之后,将指针设为NULL。
- 避免使用裸指针:尽可能使用智能指针,如
std::unique_ptr
和std::shared_ptr
。智能指针可以自动管理内存,避免内存泄漏和悬挂指针问题。 - 小心处理内存:在分配内存后,确保在不再需要时正确地释放它。否则,可能会引发内存泄漏。另外,不要试图释放未经分配的内存。
- 注意数据类型的大小和溢出:理解不同数据类型的大小以及它们可能发生溢出的方式,可以帮助你避免缓冲区溢出和其他内存安全问题。
- 使用安全的库和框架:例如,使用C 标准库和STL,它们经过了严格的测试和验证,通常比手写的代码更安全。
- 进行代码审查:让同事或其他开发人员审查你的代码。他们可能会发现你没有注意到的内存安全问题。
- 使用工具进行静态和动态分析:例如,使用Clang的静态分析工具、Valgrind等工具来帮助你发现潜在的内存安全问题。
- 学习和了解常见问题:持续学习并了解过去发生过的内存安全问题,可以帮助你避免在未来重蹈覆辙。
请注意,尽管这些建议可以帮助你避免一些常见的内存安全问题,但仍然需要谨慎编写代码,因为新的安全问题可能会不断出现。