在软件安全中,编程语言的选择是一个重要因素。在许多情况下,老代码、开发团队中的可用技术或者客户需求、环境等都可能限制编程语言的选择。在评估和选择编程语言时,你应当关注下面这些与安全相关的问题:
1、你的程序员用过哪些语言?在程序员使用自己基本没有开发经验的语言进行编码时,就更有可能犯错误。
2、该语言有助于或有碍于安全代码的开发吗?
3、该语言有可用的安全编码标准吗?
4、该语言存在哪些安全问题?有哪些策略可以减轻其威胁?其有效性如何?
权衡语言的选择:在许多情况下,语言的选择会直接影响到系统的安全性。最显著的例子是C语言和Java语言中数组边界检查的影响。虽然多数现代的C编译器支持运行时的边界检查,但该特性会造成Web服务器、操作系统、应用程序等的缓冲区溢出漏洞,但对于性能等因素非常重要的环境(如嵌入式设备和智能卡)来说,就不是那么回事儿了。Java虚拟机可能会带来太多的性能问题,导致潜在的服务被拒绝。类似的安全问题使得设计者或编码者理解某种计算机语言存在哪些弱点非常重要。如果选择了某种编程语言,设计者或编码者知道哪些弱点更容易出现也很重要。
“安全”的语言:多数“安全的”语言(或语言的变种)都是用缓冲区、指针和内存管理来避免安全问题。由微软开发的边界检查接口以及类似的接口都可以减轻由现有C程序中不正确的串管理所造成的漏洞。如果你要编制的程序将要在一个特定的暴露环境、手机、Web页面中运行,就应当使用一种包含其自身安全模式和自我保护特性的语言(例如,Java)。还有一种选择,即在主机系统上实现一种虚拟机,以包含和隔离所编制的程序。
静态类型的好处:支持静态类型的语言,如Java、F#等,都可以确保操作仅能应用于适当的类型。支持类型抽象的类型系统可以让程序员指定新的抽象类型和签名。这种类型可以防止没有经过授权的代码对特定的值实施操作。在这个方面,类型系统就超越了操作系统,因为它可以被用于强化更为广泛的访问策略类型。静态的类型系统还可以通过静态的检查来支持离线强化,而不是根据特定的操作实例来检查。这就使得类型检查器可以强化难以通过在线技术强化的规则。
内建的安全机制:较新的语言,如C#,拥有内建到语言中的许多安全机制,其中包括类型安全元素、代码访问安全和基于角色的安全,这些安全机制都包括在.NET框架中。虽然.NET框架和C#包含许多有助于安全开发的要素,开发团队仍有责任正确地开发和使用这些要素。注意,计算机语言仍有某些特性可以提供更多的安全性;不过,其它方面有可能打开新的安全漏洞。因而,对开发团队而言,有必要知道由所选择的语言导致的任何漏洞或问题。
有些语言可以通过限制程序能够激发的系统调用,来减少一些不可信的程序可能带来的破坏。Perl通过其“污染模式”来实现此功能,仅允许程序员明确设置为“清洁”的用户输入。Java提供了JVM作为沙盒,并且不允许不受信任的程序在JVM之外运行。例如,一个不可信的Java小程序就不能创建新过程或者读写本地磁盘。
不要仅依赖语言的选择:虽然选择一种安全的编程语言很重要,但许多开发者者会错误地认为安全语言是安全漏洞的万能药。不过,如果没有一个安全的开发过程,如果没有知道如何安全编码的开发人员,在将用一种语言编写的软件改为用另外一种语言编码时,就很容易出现问题。
选择健全的编程语言是编制安全程序的一个重要条件,但并非唯一要素。开发团队应当根据项目特点、具体操作环境、开发团队的人员素质等要素选择合适的编程语言。