大家好!我是大聪明-PLUS!
计算机编程错误早在编程语言发明之前就已出现。事实上,编程语言的发明正是为了简化程序编写,并最大限度地减少程序中的错误。
为了减少错误数量,人们开发了许多方法,包括创建专门的源代码分析工具,甚至创建整个编程语言。
但几十年过去了,软件中纯粹的技术错误问题至今仍未得到解决,而 Rust 语言提出的方法改变了一切。
安全内存管理的悖论
最近,Rust编程语言可谓是热门话题。它创新的"所有权和借用"模型保证了内存和线程安全,消除了许多类型的编译时错误。然而,不知为何,人们总是忽略了"所有权和借用"概念本身存在一些根本性的局限性。
例如,实现任何具有多个所有权的 算法都需要强制使用unsafe代码块或重新设计应用程序架构,这限制了 Rust 在遗留系统中的使用,因为在这些系统中,完全的代码重构在经济上是不可行的。
此外,经典形式的循环图(交叉引用)分析原则上在编译时 没有解决方案,因此总是需要手动使用智能引用计数器(Rc,Arc),这也增加了由于实现错误而导致内存泄漏的风险。
但继续使用 C++ 也行不通!C++ 语言的名字几乎已经成了各种软件漏洞的代名词。尽管它早已拥有一整套内存安全工具:智能指针(unique_ptr`std shared_ptr::vector` weak_ptr、`std::vector`、`std::vector`)、RAII 和移动语义。
然而,由于缺乏在语言语法层面应用这些安全机制的严格规则,使得它们成为"可选的"。开发者可以通过使用原始指针或不受控制的内存分配,有意或无意地绕过这些保护措施。
然而,任何试图在 C++ 中引入严格规则的尝试(例如,通过引入类似 Rust 的语法,如Safe C++)都会遇到预期的阻力,因为此类更改会破坏向后兼容性,并受到标准委员会和开发人员的拒绝,尤其是那些处理遗留代码的开发人员。
这些问题造成了一个悖论:开发人员被迫花费时间和资源用 Rust 重写现有代码,同时为了功能性而牺牲安全性,因为由于其架构的限制,Rust 无法保证在某些用例中不会出错,从而有效地抵消了其所有优势。
安全开发的现状
而这些仅仅是最显而易见的问题,它们都与内存安全管理有关。技术软件错误还可能包括各种类型的溢出:数值溢出、内存不足、栈溢出(栈空间总是预先分配的,大小固定)等等。
当然,C++ 的安全状况正在逐步改善,包括在编译器代码生成层面引入各种应用程序安全机制("加固")。然而,主要问题在于目前尚无统一的理论(或方法)来评估不同编程语言的安全开发。我们需要一种通用的理论,能够评估实现典型算法的可行性,并从代码安全性的角度比较不同编程语言。
如今,人们使用各种工具来检查源代码中的错误,从静态分析器到各种测试选项,不一而足。
此外,每种工具或方法都只测试其自身领域,但往往不清楚哪些方面被忽略了。这种情况就像一块五彩斑斓的拼布被,每一块都负责其特定的安全方面,但整块被子的整体大小却难以捉摸。
虽然这种情况曾经是常态,因为编程语言的创建者们力求实现尽可能多的功能来简化和加速编程,但如今这一趋势已发生显著变化。布鲁克斯苦苦寻觅的灵丹妙药(将开发成本降低十倍)早已被找到并投入使用,它的名字就是自由软件和开源软件。随着LLM的出现,开发标准解决方案的成本进一步降低。
因此,如今软件开发的速度比最终软件的质量更为重要。但要保证软件开发的质量,不仅需要对其进行衡量和比较,还需要了解安全开发中使用的工具(编程语言)的功能和局限性。从这个角度来看,尽管 Rust 存在一些局限性,但由于它至少提供了一些保障,因此使用 Rust 仍然是更可取的选择,而不是继续使用 C++,因为 C++ 过于宽松,即使是最愚蠢的错误也可能导致不必要的错误。
通过编程语言保证实现开发安全性
现代软件安全方法在很大程度上是分散的,主要精力集中在检测和修复已经出现的各类漏洞上。
如果漏洞或影响因素与软件源代码没有直接关系,那么这种做法或许部分合理。然而,如果漏洞纯粹是由于技术错误或编程语言特性造成的,那么在开发生命周期后期发现这些漏洞,修复成本将非常高昂。
测试、识别和实施措施以最大限度减少错误和漏洞的责任始终落在开发人员的肩上,他们不仅需要是自己领域的专家,还需要是网络安全方面的专家。
Rust 在确保软件安全开发方面展现出了卓越的方法!不仅体现在内存管理方面,更体现在转变源代码级安全的范式上,即通过编程语言的保证来确保安全性。
这种方法------使用语言及其编译器作为防止整类漏洞的主要工具------将重点从检测 漏洞转移到在最低级别(编写软件代码的级别)防止漏洞。
基于编程语言保证的安全开发具有诸多战略优势:
-
**自动漏洞修复:**由于采用了这种方法,因此可以在系统级别修复整类漏洞,而不是查找单个错误。
-
**减轻开发人员的认知负担:**开发人员可以专注于业务逻辑,完全信任编译器和类型系统来实现基本安全性。
-
**提高可预测性和可靠性:**安全性成为系统的可衡量和可证明的属性,而不是多种因素共同作用的结果,并且独立于外部工具的使用。
-
**成本效益:**在编码阶段防止漏洞比在生产环境中检测和修复漏洞要便宜几个数量级。
结论
当前软件安全领域那种修补漏洞的模式已经走到了尽头。要构建真正可靠安全的系统,必须转向内置安全------也就是基于编程语言保证的安全开发理论。这不仅仅是学术研究,而是迫切需要解决的问题。
这将使安全性能够融入软件的基础架构中,使其成为程序源代码的固有属性,并使在任何编程语言中实现安全开发保证成为一种技术问题。