图形用户界面(GUI)
这里是应对灾难的一个方案:一个进程拥有特别的特权(例如,如果它设置了 setuid/setgid),它使用操作系统的图形用户界面(GUI)库,而且 GUI 用户不是完全可信任的。问题是,GUI 库(包括 Unix 的、Linux 的和 Windows 的)并不是设计这样使用的。这样做也不现实 —— GUI 库很大,而且依赖于庞大的基础结构,所以很难为了安全性而去分析所有的代码。GTK+ GUI 库当发现它是在 setuid 程序中运行时甚至会停止,因为它没有假定会这样使用(感谢 GTK+ 的开发者主动预防了这一安全问题)。
难道这意味着您只能使用命令行?不是。将您的程序分为小一些的部分,用没有特权的部分去实现 GUI,用单独的部分去实现需要特权的操作。下面是一些常见的做法:
l 通常,简单的方法是将有特权的操作作为命令行程序来实现,由 GUI 调用 —— 那样您可以“无偿地”获得 GUI 和命令行界面(CLI),从而简化了脚本编写和调试。典型地,CLI 特权程序是一个 setuid/setgid 程序。当然,有特权的程序必须保护自己不受攻击,但是这个方法通常意味着这一部分必须是安全的程序,这些程序应更小并且更容易保护。
l 如果您需要高速通信,将这个程序作为有特权的程序启动,把它分为可以安全通信的独立的进程,然后将一个进程永久释放特权并去运行 GUI。
l 另一种方法是实现有特权的服务器来响应请求,并创建 GUI 作为客户机。
l 使用 Web 界面;创建一个有特权的服务器,然后使用 Web 浏览器作为客户机。这实际上是先前方法的一个特例,但它很灵活,因此通常值得考虑。如任何其他为我们带来网络数据问题的 Web 应用程序一样,您将需要使它安全。
网络数据
如果数据来自于网络,您应该认为它是高度不可信的。不要相信“源 IP”地址、HTTP“Referrer”头的值或者类似的数据所告诉您的数据来自何方;那些来自发送者的值可以被伪造。当心来自域名系统(DNS)的值;DNS 实现的是一个分布式数据库,那些值中有一些可能是攻击者提供的。
如果您有一个客户机/服务器系统,服务器应该永远不要相信客户机。客户机数据在到达服务器前可以被操纵,客户机程序可能已经被修改,或者攻击者可能创建了他们自己的客户机(很多这种情况!)。如果您正在从 Web 浏览器获得数据,不要忘记 Web cookie、HTML 表单数据、URL 等可以被用户设置为任意的值。这是网络购物车应用程序中常见的问题;许多这样的应用程序使用隐藏的 HTML 表单域来存储产品信息(比如价格)和相关信息(比如运费),当用户发送这些值时就盲目地接收。用户不仅能将产品价格设置为更低的值或者零,有时他们还可以设置负值的价格,以得到商品和附加的现金反款。记住,必须检查 所有的数据;有一些网络购物车检查了产品数据却忘记去检查运费。
如果您正在编写一个 Web 应用程序,查询数据时要限制使用 GET 请求。不要让 GET 请求实际上去改变数据(比如传输的钱数)或者进行其他行为。用户很容易被欺骗去点击他们 Web 浏览器中恶意的超链接,这样就会发送 GET 请求。相反,如果您得到的 GET 请求有查询以外的行为,那么返回一个“you asked me to do X,is that okay? (Ok,Cancel)”格式的确认消息。注意,限制 GET 查询不能帮您解决错误的客户机数据的问题(如先前段落所讨论的) —— 服务器还是需要检查来自它们的客户机的数据!
其他来源
程序有很多其他的输入,比如当前目录、信号、内存映射、System V IPC、umask、文件系统状态。有了在这里获得的信息,重要的是不要忽略这些也可以作为输入,即使它们有时看起来不像是输入。
结束语
安全的程序必须检查每一个不可信的输入通道,这样做可以避免很多问题。但是那也还不够。有时,即使只是读入数据也可以是安全漏洞 —— 甚至在数据被检查之前!处理数据可以导致程序以可怕的方式失败。我们将要讨论的是当前第 1 号安全漏洞 —— 缓冲区溢出。我的下一期文章将论述这个漏洞是什么样的,如何进行防范,以及为什么可以期望它未来将不再是问题。
共6页: 上一页 [1] [2] [3] [4] 5 [6] 下一页
|