18.2 Running a Secure ServerWeb servers are designed to receive anonymous requests from unauthenticated hosts on the Internet and to deliver the requested information in a quick and efficient manner. As such, they provide a portal into your computer that can be used by friend and foe alike. No piece of software is without its risk. Web servers, by their nature, are complicated programs. Furthermore, many organizations use Web servers with source code that is freely available over the Internet. Although this means that the source code is available for inspection by the organization, it also means that an attacker can scan that same source code and look for vulnerabilities. The ability to add functions to a Web server through the use of CGI scripts tremendously complicates their security. While a CGI script can add new features to a Web server, it can also introduce security problems of its own. For example, a Web server may be configured so that it can only access files stored in a particular directory on your computer, but a user may innocently install a CGI script that allows outsiders to read any file on your computer. Furthermore, because many users do not have experience in writing secure programs, it is possible (and likely) that locally written CGI scripts will contain bugs allowing an outsider to execute arbitrary commands on your system. Indeed, several books that have been published on CGI programming have included such flaws. Because of the richness of its tools, the plethora of programming languages, and the ability of multiple users to be logged in at the same time from remote sites over a network, the UNIX operating system is a remarkably bad choice for running secure Web servers. Because many PC-based operating systems share many of these characteristics, they are also not very good choices. Experience has shown that the most secure Web server is a computer that runs a Web server and no other applications, that does not have a readily accessible scripting language, and that does not support remote logins. In practice, this describes an Apple Macintosh computer running M ac HTTP , WebStar, or a similar Web server. According to recent surveys, such computers comprise as many as 15% of the Web servers on the Internet. Of course, there are many advantages to running a Web server on a UNIX computer instead of a Macintosh. UNIX generally runs faster than MacOS on comparable hardware, and UNIX is available for hardware platforms that run faster than PowerPC-based computers. Furthermore, it is generally easier for organizations to integrate UNIX -based Web servers with their existing information infrastructure, creating interesting possibilities for Web offerings. Finally, more MIS professionals have familiarity with building UNIX -based Internet servers than with building MacOS-based ones. Nonetheless, we suggest that the security-conscious administrator give the Mac-based approach serious thought. To build a secure Web server on any platform, you must be able to assure a variety of things, including:
The following sections explore a variety of techniques for dealing with these issues. 18.2.1 The Server's UIDMost Web servers are designed to be started by the superuser. The server needs to be run as root so it can listen to requests on port 80, the standard HTTP port. Once the server starts running, it changes its UID to the username that is specified in a configuration file. In the case of the NCSA server, this configuration file is called conf/httpd.conf . In the file, there are three lines that read: # User/Group: The name (or #number) of the user/group to run httpd as. User http Group http This username should not be root . Instead, the user and group should specify a user that has no special access on your server. In the example above, the user changes his UID to the http user before accessing files or running CGI scripts. If you have a CGI script that is to be run as superuser (and you should think very carefully about doing so), it must be SUID root . Before you write such a script, carefully read Chapter 23 .
18.2.2 Understand Your Server's Directory StructureWeb servers are complicated pieces of software. They use many files in many directories. The contents of some directories are made available over the network. The contents of other directories must not be made available over the network, and, for safety, should not be readable by users on your system. To run a secure server, you must understand the purpose of each directory, and the necessary protections that it must have. The NCSA sever has six directories:
Many sources recommend creating a user called www and a group called www which can be used by the Web administrator to administrate the Web server: drwxr-xr-x 5 www www 1024 Aug 8 00:01 cgi-bin/ drwxr-x--- 2 www www 1024 Jun 11 17:21 conf/ -rwx------ 1 www www 109674 May 8 23:58 httpd drwxrwxr-x 2 www www 1024 Aug 8 00:01 htdocs/ drwxrwxr-x 2 www www 1024 Jun 3 21:15 icons/ drwxr-x--- 2 www www 1024 May 4 22:23 logs/ This is an interesting approach, but we don't think that it adds much in the way of security. Because the httpd program is run as root , anybody who has the ability to modify this program has the ability to become the superuser. This is a particular vulnerability if you should ever move the server or configuration files onto an NFS -exported partition. Therefore, we recommend acknowledging this fact, and setting up your Web server directory with root ownership: drwx--x--x 8 root www 1024 Nov 23 09:25 cgi-bin/ drwx------ 2 root www 1024 Nov 26 11:00 conf/ drwxr-xr-x 2 root www 1024 Dec 7 18:22 htdocs/ -rwx------ 1 root www 482168 Aug 6 00:29 httpd* drwxrwxr-x 2 root www 1024 Dec 1 18:15 icons/ drwx------ 2 root www 1024 Nov 25 16:18 logs/ drwxr-xr-x 2 root www 1024 Aug 6 00:31 support/ Notice that the cgi-bin directory has access mode 711; this allows the httpd server to run programs that it contains, but it doesn't allow a person on the server to view the contents of the directory. More restrictions make probing for vulnerabilities more difficult. 18.2.2.1 Configuration filesInside the conf directory, the NCSA server has the following files:
Because the information in these files can be used to subvert your server or your entire system, you should protect the scripts so they can only be read and modified by the superuser: -rw------- 1 root wheel 954 Aug 6 01:00 access.conf -rw------- 1 root wheel 2840 Aug 6 01:05 httpd.conf -rw------- 1 root wheel 3290 Aug 6 00:30 mime.types -rw------- 1 root wheel 4106 Nov 26 11:00 srm.conf 18.2.2.2 Additional configuration issuesBesides the setting of permissions, you may wish to enable or disable the following configuration options:
Some servers, such as the NCSA server, allow you to limit processing of server-side includes to specific directories. The NCSA server uses the Options directive to control includes. Specify the option Includes for all server-side includes; specify the option IncludesNOEXEC to specify textual includes but to disable the execution of commands.
18.2.3 Writing Secure CGI Scripts and Programs[1]
Writing a secure CGI script has all of the same problems as writing a secure SUID program or network server, plus many more. That's because there can be unexpected interactions between the Web environment, the Web server and the CGI script, creating problems with the combined system where no problems obviously were present in any single part. Therefore, we recommend that you read Chapter 23 before you embark on writing CGI scripts. In addition to the information that we describe in that chapter, there are additional issues in writing programs for the World Wide Web. Most security holes are not intentional. Nonetheless, the more people who have the ability to write scripts on your Web server, the greater the chance that one of those scripts will contain a significant flaw.
18.2.3.1 Do not trust the user's browser!HTML includes the ability to display selection lists, limit the length of fields to a certain number of characters, embed hidden data within forms, and specify variables that should be provided to CGI scripts. Nevertheless, you cannot make your CGI script depend on any of these restrictions. That is because any CGI script can be run by directly requesting the script's URL ; attackers do not need to go through your form or use the interface that you provide. Be especially careful of the following:
Attackers are by definition malicious. They do not follow the rules. Never trust anything that is provided over the network. 18.2.3.2 Testing is not enough!One of the reasons that it is surprisingly easy to create an unsecure CGI script is that it is very difficult to test your scripts against the wide variety of HTTP clients available. For example, most client programs will "escape," or specially encode, characters such as the backquote (`), which are specially interpreted by the UNIX shell. As a result, many CGI programmers do not expect the unencoded characters to be present in the input stream for their applications, and they do not protect their scripts against the possibility that the characters are present. Nevertheless, it is easy for the characters to be in the input stream, either as the result of a bug in a particular Web browser or, more likely, because a malicious attacker is attempting to subvert your CGI script and gain control of your server.
By all values, we mean all values . This includes the contents of environment variables, host addresses, host names, URLS , user-supplied data, values chosen from selection lists, and even data that your script has inserted onto a WWW form through the use of the hidden data type. Consider the case of a CGI script that creates a series of log files for each host that contacts your WWW server. The name of the log file might be the following: logfile/{hostname}. What will this program do if it is contacted by the "host" ../../../../etc/passwd.company.com ? Such a script, if improperly constructed, could end up appending a line to a system's /etc/passwd file. This could then be used as a way of creating unauthorized accounts on the system. Many programming languages, including C, ksh , sh , csh , and Perl, provide the means to spawn subprocesses. You should try to avoid using these features when writing CGI scripts. If you must spawn a subprocess, avoid passing through any strings that are provided by the user. If you must pass strings from the user to the subprocess, be sure that it does not pass shell meta characters including the `$|;>*<&> characters. It is generally better to specify a list of allowable characters than to specify a list of dangerous characters. If you forget to specify an allowable character, there is no real harm done. But if you forget to specify a dangerous character, such as a backquote, you can compromise the security of your entire system. 18.2.3.3 Sending mailIf you are writing a CGI script that allows a user to send mail, use the /usr/lib/sendmail program to send the mail, rather than /bin/mailx or /usr/ucb/mail . The reason is that /usr/lib/sendmail does not have shell escapes, whereas the other mailers do. Here is a bit of Perl that you can use to send mail securely. It bypasses the shell by using exec ( ) with a fixed string to run /usr/lib/sendmail directly: open (WRITE, "|-") || exec ("usr/lib/sendmail", "-oi," "-t") || die "Can't fork$!\n": print WRITE "To: $address\n"; print WRITE "Subject: $subject\n"; print WRITE "From: $sender\n"; print WRITE "\n$message\n.\n"; close(WRITE); There are many commands in Perl that will run the shell, possibly without your knowledge. These include system ( ), eval ( ) , pipes, backquotes, and, occasionally, exec ( ) (if shell meta characters are present on the command line). 18.2.3.4 Tainting with PerlIf you are using the Perl programming language, you can use Perl's "tainting" facility to track information that has been provided by the user. Perl marks such information as "tainted." The only way to untaint information is to match it using a Perl regular expression, and then to copy out the matched values using Perl's string match variables. For example, if you have a name that has been provided by the user, you can untaint the value to be sure that it only contains letters, numbers, commas, spaces, and periods by using the following Perl statements: $tainted_username =~ m/([a-zA-Z. ]*)/; $untainted_username = $1; You can use the following to extract an email address: $tainted_email =~ /([\w-.%]+\@[\w.-]+)/; $untainted_email = $1; There are two ways to enable tainting. If you are using Perl 4, you should invoke the taintperl command instead of the Perl command, by placing the following statement (or something similar) at the beginning of your file: #!/usr/local/bin/taintperl If you are using Perl version 5, you accomplish the same result by using the -T flag: #!/usr/local/bin/perl -T 18.2.3.5 Beware stray CGI scriptsMost Web servers can be configured so that all CGI scripts must be confined to a single directory. We recommend this configuration, because it makes it easier for you to find and examine all of the CGI scripts on your system. We do not recommend the practice of allowing any file on the Web server with the extension " .cgi " to be run as a CGI script. Instead, we recommend that you:
18.2.4 Keep Your Scripts Secret!Throughout this book, we have railed against the practice of security through obscurity - the practice of basing some of the security of your system upon undocumented aspects. Nevertheless, the fact remains that the ready availability of UNIX source code, as opposed to the relative "obscurity" of the source code for other operating systems such as VMS or Windows/NT, means that potential attackers can search through the operating system looking for avenues of attack, and then craft their attacks in such a way as to guarantee the maximum possible access. One good way to prevent these sorts of attacks is to limit the access to source code. Because it is so easy to make a mistake when writing a CGI program, it behooves sites to keep your CGI scripts and programs confidential. This does not guarantee security for buggy scripts: a determined attacker can still probe and, frequently, find flaws with your system. However, it does significantly increase the work that is involved. Determined attackers will still get through, but casual attackers may move on to other, more inviting systems.
18.2.4.1 Beware mixing HTTP with anonymous FTPMany sites use the same directory for storing documents that are accessed through anonymous FTP and the World Wide Web. For example, you may have a directory called /NetDocs on your server that is both the home directory of the FTP user and the root directory of your Web server. This would allow files to be referred to by two URLS , such as http://server.com/nosmis/myfile.html or ftp://server.com/nosmis/myfile.html. The primary advantage of HTTP over FTP is speed and efficiency. HTTP is optimized for anonymous access from a stateless server. FTP , on the other hand, had anonymous access added as an afterthought, and requires that the server maintain a significant amount of state for the client Mixing HTTP and FTP directories poses a variety of security issues, including:
18.2.5 Other IssuesThere are many other measures that you can take to make your server more secure. For example, you can limit the use of the computer so that it is solely a Web server. This will make it harder for an attacker to break in to your server and, if an attacker does, it will limit the amount of damage that he can do to the rest of your network. If you do chose to make your server a stand-alone computer, read over Chapter 21, Firewalls , for a list of techniques that you can use to isolate your computer from your network and make the computer difficult for an attacker to use. In particular, you may wish to consider the following options:
Another option, but one that may require a non-trivial amount of work, is to place your WWW server and all files in a separate directory structure. The WWW server is then wrapped with a small program that does a chroot ( ) to the directory (see Chapter 22, Wrappers and Proxies ). Thus, if some way is found to break out of the controls you have placed on the server, the regular filesystem is hidden and protected from attack. Some WWW servers may have this approach included as an install-time option, so check the documentation. | ||||||||||||||||||||||||
|