目录:
1. 基本的安全问题
1-1. 操作系统
1-2. 增强服务器的安全
1-2-1.你应该在什么地方放置你的cgi程序?
1-2-2.ssi(server-side includes)
1-2-3.增强你的unix服务器的安全
1-2-4.例子:安全的配置ncsa服务器
2.写出安全的cgi程序
2-1.语言的风险性
2-2.shell危险性
3.安全处理
3-1.ssl
3-2.shttp
4.概要
如果你以前从未编写过应用于网络的软件,那么安全问题可能是你在编程时最不注重的了。毕竟,在单机上,你没有必要担心写了不安全的程序,因为,大概也只能有一个人可以接近那台计算机。
但是,在编写应用于inte.net的软件中需要非常强调安全问题。有一个挺老的计算机格言说:"使一台计算机真正安全的唯一方法是将它与世界断开连接并把计算机放到紧锁的房间里。"可见,将计算机和一个网络简单相连就会降低你的计算机的安全性。
对于越大的相连的网络这句话越适用,比如inte.net,这里有成千上万的人可能会访问你的计算机。很多基于inte.net的服务,特别是www,别设计成能使其他人很容易的从你的计算机中获取信息。这些你允许接受访问的服务(或者是有意的,或者是无意的)都有可能成为老谋深算、心怀恶意的人的攻击途径。一个很糟糕的网络服务器很容易被攻破,甚至潜在给出了可以访问你的整个计算机和重要数据的权限。
我说你提供的每一项网络就象进入你系统中另一个门,是指什么呢?什么才是安全破坏呢?不管是什么目的,安全破坏是指一个人从你的计算机中获得了未经授权的访问权。"unauthorized access"(未经授权的访问权)也可以理解为很多事情,试图从服务器上运行一个非公共的程序,甚至是获得在unix中获得root权限。
你过多的依赖于为网络服务器编写安全程序的程序员的知识和细心。毕竟,没有人指望你详细审查几千行的源码只为了弄清楚软件是否有安全漏洞;大多数情况,你依赖编程者的可靠性和其他审阅源码和仔细的帮助测试软件的专家。假如网虫们证明了你不能完全相信这些程序员可以写出完美的安全的代码,那么你可以采取措施最大限度的减少风险。
在后面的"保护你的web服务器",你将学习web服务器的安全。目前,假定你的应用于web服务器的软件是安全的,并且正确的配置了;也就是说,没有人可以仅仅通过你的web服务器从你的机器中获得未经授权的权限。为什么写安全的cgi脚本很重要呢?cgi是一个允许你拓展web服务器的一般协议。通过编写cgi程序,你能够增加web服务器的功能。这些功能很可能无意中引入新的安全漏洞。一个糟糕的cgi应用程序很可能允许任何人拥有你的机器的完全的权限。
用户提交一个表单或者是以另一种方式访问cgi脚本的时候,本质上来说,是你允许他们远程运行你的服务器中的应用程序。因为很多的cgi应用程序接受用户的表单输入(或通过填写表,或是通过命令行),从另一个角度来说,你允许用户控制cgi程序的运行。作为cgi程序的作者,你需要确定你的cgi脚本只能用来实现它指定的功能。这一章提到了相关的web安全问题,提供了编写安全的cgi程序的深入的资料。在本章的最后,你也会学会怎样安全的编写cgi。
1. 基本的安全问题
你的web服务器的全面的安全性取决于很多因素。如果你的web服务器没有正确配置或者系统有其它漏洞的话,那么一个安全的cgi程序也是毫无用处的。这里,我论述一些相关的web安全问题,并说明如何为cgi程序正确的配置你的web服务器。
1-1. 操作系统
一个通常的问题是什么样的平台对web服务器来说更安全?运行system 7的macintosh,unix的工作站,运行os/2或linux的pc等等。在这个问题上有过很多争论,这些反映了人们对不同的操作系统的不同的偏爱。
没有一个操作系统比另外一个明显安全。unix被认为比单用户的平台(比如acintosh或者是运行着windows的pc)更安全,因为曾经有人攻破过一些运行着后者(注:括号中)的机器,并拥有了所有文件的权限。然而对于unix,有一个关于文件属主和权限的基本的理解。如果你的服务器正确的配置了,并被一个安全的用户(比如:非root用户)拥有,这时候,如果未经授权的用户闯进来,他(她)只能造成有限的破坏。然而,有限的破坏已经够糟糕了,在以后的章节的例子中你会明白。
另一方面,因为unix经常要配置很多不同类型的网络服务,比如mail,ftp,gopher,www等等,因此,有更多的潜在的“后门”。加强这些服务的安全性是一个耗时的过程,甚至对有经验的系统管理员亦如此。即使你每项配置正确无误,然而在每个单独的软件包里仍有可能出现恼人的bug。安全漏洞在各种软件包中并不是罕见的,从一些组织(比如cert(the computer emergency responseteam))的有关各种的unix网络服务周期性的通知中我们可以清楚的了解到。
每一个不同的平台都有其不同的安全含意,但是不能彼此比较安全性。尽管你应该注意每个操作系统的安全性,但是这不应该成为你选择平台的主要标准。选择你的平台,纠正有关该平台相关的安全漏洞,然后安全正确的配置你的web服务器。在你完完全全的完成这些步骤之后,你才应该将你的精力投入到编写安全的cgi脚本中去。
1-2. 保护你的服务器
编写安全的cgi脚本的第一步要确定你安全并正确的配置了你的web服务器。如果你的web服务器并不可靠,那即使你再仔细编写你的cgi脚本也是没有用的,人们仍然可以闯入你的计算机。而且,正确的配置你的web服务器能够减小糟糕的cgi程序所带来的可能的危害。
more:选择一个安全的web服务器
在不同的平台有数不清的web服务器可供使用。如果可能的话,自我确定一个产品是否安全是很困难的,你将不得不依靠公司的信誉和口头承诺。
检查你的选择。在你拥有了一个web服务器的列表之后,看一下每个产品的有效期以及目前有多少人使用它。越老的并且经常使用的web服务器,有关的安全方面的bug越有可能被发现并修补。如果源码是开放的,并且你有时间和专门技术,自己从头至尾看一下源文件,看看能否找到潜在的漏洞。阅读网络中不同的新闻组对该产品以及作者和发行人的评论。著名的公司或作者会很快的通知用户其产品的任何问题。阅读各个组织(如ciac(computer incident advisorycapability)和cert)有关安全方面的警告信息。
检查所有的服务器组件并确定你是否真的需要所有组件的特性。越复杂、功能越强大的服务器,越有可能存在未被发现的安全问题。确定你的服务器支持日志功能,这样你可以跟踪安全问题或其它故障的原因。
有一个对付意外事件的计划。如果发现安全漏洞,要随时准备升级或者替换你的web服务器。关注新版本的发行和新闻组中有关你的web服务器的信息。尽量使用web服务器最新的非测试的版本。
不必担心免费的服务器。关于开发源码使服务器更安全或者相反有争论。如果服务器的源码不公开,安全漏洞将更难发现。如果源码公开,那么,理论上,漏洞将很快被发现,公开并得到修补。
在增强服务器的安全性时,应该有三个目的:
a.配置你的程序使它只能提供你指定的服务。
b.不到必要的时候不暴露任何信息。
c.如果系统遭到入侵,最大限度地减少损坏。
我知道的有关你的计算机的信息越多,我就越有机会闯入你的计算机。例如,如果我知道哪个目录或者文件夹存储了你的所有的敏感的、私有的信息,这样,我将进入你的系统获取全部访问权缩小至只是获得某个目录的权限(通常是更容易了)。或者,如果我可以访问你的服务器配置文件或源码或者是你的cgi脚本,那我可以很容易的浏览它们来寻找安全漏洞。如果你的系统有漏洞,你不想让别人轻易知道,你必须在别人之前发现它们。
1-2-1.你应该在什么地方放置你的cgi程序?
很多服务器允许你通过各种不同途径来运行cgi程序。例如,你可以指定一个特定的目录作为你的cgi-bin。或者,你可以允许cgi存放在任何目录下。
这两种方法都有优缺点,但是从安全的角度来说,在一个指定的目录中放置你的所有的cgi应用程序更好。把所有的程序放到同一个目录使你很容易跟踪你服务器器所有的应用程序并审查它们的安全漏洞,同时,还可以防止被恶意修改。
如果你倾向于使用描述型的语言(例如perl)来编写你的大部分的应用程序,那么源码被包含在程序自身中。如果你不小心的话,这些代码很容易被阅读,甚至被利用。例如,很多文本编辑器存储备份的文件,通常在文件名的后面加一个扩展名(比如.bak)。
举个例子,emacs使用扩展文件名~存储备份文件。假设你使用perl编写了一个cgi脚本——program.cgi——存储在web的数据目录而非中心的指定的目录中。现在,假设你使用emacs对程序做了一些琐碎的修改而忘记了删除备份文件。现在,在你的目录里有了两个文件:program.cgi和program.cgi~。web服务器知道以.cgi结尾的文件是cgi程序,它会运行这个程序而不是显示它的内容.然而,聪明的用户可能尝试访问program.cgi~.因为它不是以.cgi结尾,你的web服务器将它以原始的文本文件发送出去,这样就允许用户查看你的源代码来搜寻可能的漏洞.这违反了避免暴露不必要信息的原则.
当然,如果你的服务器允许你指定位于某一特定的目录下的文件均为cgi,那么这个文件的扩展名是什么也就无关紧要了.这样,在前面的例子中,如果备份文件放在这样特定的目录里,当用户试图访问它时,服务器就会运行这个程序而不是发送源代码.
注意到在你的服务器中指定一个中心目录作为cgi程序的存放位置是有限定的,特别是在多用户系统中.例如,如果你是一个isp(inte.net service provider)并且你想让你的的用户可以编写并运行他自己的cgi程序,你可能有意允许cgi程序可以存放在任何的目录中.做这个之前,认真考虑一下可替换的选项.你的客户们打算写很多的特定的个性化的脚本吗?如果不是,最好是让你的客户将他的cgi脚本提交给你,然后由你将其添加到cgi-bin目录中,而不要允许cgi可在任何目录中有效.
关于cgi程序的位置另外一个问题是将解释器放在哪里.解释脚本时,服务器运行解释器,由它顺序装载脚本并执行.
不要将解释器放到你的cgi-bin目录中,或其他有关你的数据结构的任何目录中.给了用户访问解释器的权限本质上就是给了他们运行你的系统中任何程序或命令的权力.
如果你使用windows或其他的非unix操作系统,这尤其重要.在unix系统中,你可以在脚本的第一行中指定解释器.例如:
#!/usr/local/bin/perl
# this first line says use perl to run the following script
在windows中,举个例子,没有类似在脚本中指定解释器的方法.一个调用perl脚本的方法是建立一个批处理文件来调用perl和脚本:
rem progname.bat
rem a wrapper for my perl script, progname.pl
c:\perl\perl.exe progname.pl
然而,你也许倾向于避免建立额外的程序,只是简单的将perl.exe放在你的cgi-bin
目录中,并访问如下的url:
http://hostname/cgi-bin/perl.exe?progname.pl
Java Asp PHP .Net XML C/C++ CGI VB Jsp J2ee J2se J2me EJB Servlet Tomcat Resin Struts Weblogic Eclipse ANT GUI JMS Web servise IDEA Webphere Hibernate Spring Jboss Applet Swing Socket Javamail Perl Ajax P2P 安全 模式 框架 测试 开源 游戏
Windows XP Windows 2000 Windows 2003 Windows Me Windows 9.x Linux UNIX 注册表 操作系统 服务器 应用服务器