许多不同类型的程序可能都需要成为安全程序(按照本文的定义)。一些通用的类型为:
用来浏览远端数据的应用程序。用做浏览器的程序(如文字处理程序或文件格式浏览器)经常需要浏览一个不可信的用户从远端发来的数据(一个网页浏览器会自动执行这种请求)。显然,不应当允许一个不可信用户的输入使应用程序运行任意的程序。支持预置的宏(在显示数据时运行)通常是不明智的;如果必须这么做,那么应该创建一个安全沙箱(这是一个复杂而且容易出错的工作)。小心处理下面会讨论的缓存溢出一类的问题,它会允许一个不可信用户强迫浏览器运行一个任意程序。
系统管理员(root)使用的应用程序。这类程序不应当信任非系统管理员就可以控制的信息。
本地服务器程序(也被称为daemon)。
可访问网络的服务器程序(有时被称为网络daemon)。
CGI脚本程序。这些是一类特殊的可访问网络的服务器程序,但应用得十分普遍,应当算作一个单独的类别。这样的程序通过一个WEB服务器被间接地执行,虽然WEB服务器可以过滤掉一些攻击,但仍然需要抵抗许多攻击。
setuid/setgid程序。这些程序由一个本地用户执行,但在执行时会立刻拥有程序所有者或其所在群组的特权。从很多方面来说,这些是最难保证安全的程序,因为它们有很多输入是在不可信用户的控制之下,而且有些输入不是很明显的。
本文把这些不同类型的程序都归为一类。这样做的不利之处在于本文指出的某些问题不适用于所有类型的程序。特别是setuid/setgid程序有很多令人惊奇的输入,本文有几条只针对它们的准则。然而事情并非如此简单界定的,一个特定的程序可能无法进行这样的分类(例如,一个CGI脚本程序可以setuid或setgid,或者进行有同样效果的配置),而且有些程序可以分为若干个可执行部件,每个都可以被认为是一个不同“类型”的程序。把这些不同类型的程序都归为一类的好处在于考虑问题时不会把一个不适当的类别应用在某个程序上。在下面你将看到,很多原则都可以应用到所有需要安全的程序上。
本文对C编写的程序有一些偏爱,也有一些关于其它语言如C++、Perl、Python、Ada95和Java的说明。这是因为C是在Linux下实现安全程序最普遍的语言(CGI脚本程序倾向于使用Perl),而且大多数其它语言的实现都调用C库。这并不意味着在实现安全程序时C是“最好”的语言,无论使用的是哪一种编程语言,本文所说明的原则绝大多数都适用。