Sunday, July 24, 2011

CGI-BIN Specific Vulnerabilities

CGI-BIN programs are very popular, are commonly written by inexperienced coders, and are by default available via network to outside users. These factors combine to make CGI-BIN programs a major source of system vulnerabilities. This document highlights the more common types of CGI-BIN vulnerabilities and provides guidelines for secure CGI programming.

Types of CGI vulnerabilities

There are two ways in which CGI script vulnerabilities tend to manifest. The first is by leaking system information that should be kept confidential, and the second by allowing remote users to execute inappropriate commands.

The first case is less immediately dangerous, but harder to protect against. Practically any piece of system information can be useful to a sufficiently wily attacker, and many useful functions require the system to provide some data about itself. Some kinds of information that should not be disclosed without excellent justification include physical paths to users' home directories, such as is returned by the finger daemon, information about what programs users are running, such as is given by the w command, and information on which daemons are running on the system, such as is returned by ps.

The second case represents a much more direct threat to the integrity of the system. CGI scripts will generally be executed with the privilege of the web server; so if that server is properly set up as an unprivileged user then damage will usually be constrained to those parts of the system to which the server has access. Common effects of such vulnerabilities include defacement of the web site and denial of web service.

It does remain possible, however, that a vulnerability in a script that interacts with system calls or other programs on the system could result in a more serious breach. The easiest way to create a root-level hole through CGI programming is to have a setUID script on the system.
Finally, note that all of the general programming security concerns apply to CGI programs like they do to any others.

Methods for Secure CGI scripting

First let it be said that none of these techniques will completely eliminate the problem of CGI vulnerabilities. They can only reduce the risks of an exploit. If any chance of a vulnerability existing on the server is unacceptable, the solution is to disallow CGI scripts entirely.

Configuring the Server

The first technique by which the security of CGI scripts may be improved is proper configuration of the web server from which they will be executed.Most servers have a script-aliasing mode, which allows scripts to be called only from a specified cgi-bin directory. Using this mode will not only allow the administrator to keep better track of what scripts are on the system, it will also prevent an attacker who has compromised another area of the filesystem from installing scripts for his own use.

Turn off the server's dynamic index function. This feature will send a client a listing of any directory to which the server has access when the client requests the directory as a URL. If applied to the cgi-bin directory, this gives an attacker an easy list of all scripts and associated files running on your system.

Most servers come with a selection of pre-built sample scripts. Because these scripts are widely distributed, attackers know to look for them and may blindly request those that then know of vulnerabilities in even if they cannot obtain a listing of scripts on the system. Remove all unneeded sample scripts, and be attentive to any news of vulnerabilities in the ones that you do use. The danger presented by using well known scripts can also be reduced somewhat by simply renaming those scripts so that blind requests will fail.

Setting Permissions

Another major area for improving CGI script security is permission settings. It is a fundamental principle of security that the privilege of any user or process be restricted to what is absolutely necessary.

The most important permission to set is that of the web server. The most common and easiest to exploit CGI vulnerabilities leave the attacker in possession of whatever privileges the web server possesses. Servers should never be run as any sort of privileged user if security is of any concern. Instead run the server as an equivalent of UNIX's nobody user, or create an unprivileged account just for the web server. The advantage of the second approach is that it prevents an attacker who compromises nobody through a different route from also gaining control over the web server.

Running the web server without privileges does not help CGI security if the scripts run from that server gain privilege through sUID. In general, avoid sUID scripts like the plague. Any vulnerability in such a script is a direct conduit for an attacker into the account that the script is set to. Since the whole point of sUID is to give the script some sort of privilege, this invariably translates to some kind of serious security breach. If an sUID script is necessary, be aware that it will become a focal point for attacks into the system. Scrutinze the code for vulnerabilities before installing, and check up regularly once it is in production to ensure that it has not been tampered with.

It is insufficient to restrict access to forms. CGI scripts are usually intended to be called via HTML forms, which often gives web admins the impression that this is the only way that they may be called. This is untrue. A user can call a script directly by requesting it from the web server and including its arguments in the URL. Therefore the permissions of the script files themselves must be restricted.

To secure the scripts themselves, have the cgi-bin directory owned by a secure account--the web admin would be a good choice--and set its permissions such that anyone can execute programs within it but that only its owner can read or write. Unauthorized read access to the scripts only means that an attacker can gain a list of the scripts on the system and source code for that are written in interpreted languages. Unauthorized write access constitutes a full breach of the web server, because the attacker can install arbitrary code and induce the server to execute it.

Any sort of sophisticated scripting will need to write out data, but the scripts run without privilege, and the cgi-bin directory can only be written to by the web admin. The secure solution is to create a separate cgi-data directory. This directory should be owned by whoever owns the cgi-bin directory, but its permissions should be set such that anyone can read and write, but only the author can execute. If the system has any mechanism for indicating trust in information, the data in this directory should be labelled minimum-trust.

A privilege problem that arises on multi-user systems, is that, with only one cgi-bin directory, every user has access to all other users' scripts. This is a problem both because it allows users no confidentiality or integrity for their CGI scripts, and because it gives the administrator no way to establish accountability for problems arising due to user scripts. The solution is to employ CGI-wrapper programs that allow scripts to be readable and writable only by their authors, and to run with the privileges of their authors. The downside to this solution is that wrapped scripts have the necessary permissions to compromise their authors' files. Several wrapper programs, each with slightly different features, are freely available:
cgiwrap, written by Nathan Neilinger:
sbox, written by Lincoln Stein:
suEXEC, which is part of the Apache web server.

Checking Input

Input gathered from CGI scripts is often passed to other programs or to a shell for further processing. This presents an opportunity for vulnerabilities when the script interprets input differently from the entity that it is interfacing with. The most common way in which this type of vulnerability is exploited is when an attacker gives the script input containing characters that have special meaning to the program being called.The classic example, from the Safe CGI Programming guide is an HTML form like

<INPUT TYPE="hidden" NAME="FooAddress" VAULE="">
calling a script with the line
system("/usr/lib/sendmail -t" + FooAddress + " < " + InputFile);
The script is intended to allow web users to send email to foo, but if an attacker calls the script with the altered form
<INPUT TYPE="hidden" NAME="FooAddress" VALUE=";mail < /etc/passwd"/>

Then the shell will interpret the ";" character as "start new command here," and will mail the system's password file to the attacker.

In UNIX, the shell is the primary source of such misunderstandings. So the security of a script can often be improved simply by avoiding opening a shell. The problem code in the example could be replaced with
open(MAIL, "|/usr/lib/sendmail -t");
print MAIL "To: $recipient\n";
Sometimes opening a shell is unavoidable, however, and programs other than the shell are still perfectly capable of misbehaving when give unexpected input. The general solution is to determine which characters a user should legitimately be able to input, and either strip out or escape all others.
The other frequently exploited vulnerability arising from improper input is the unchecked buffer problem. If the size of input data is larger than the variable designated to store that data, then an attacker may be able to crash the server or possible execute arbitrary code with the server's privileges. Some scripting languages, like Perl, automatically ensure that a variable will have enough space assigned to it to store incoming information. Scripts written in less buffer-aware languages should be checked thoroughly to ensure that the size of incoming data is always checked or limited before it is placed into a buffer.

Observing General Precautions

Finally, be aware that CGI programming is subject to the same general security concerns shared by all types software.
Use open source whenever possible. This is advisable both so that web admins or security officers can personally inpect the scripts that are hosted on the system, and so that many others can inspect those scripts and catch vulnerabilities that the local administrators may have missed.Keep source code short and understandable. This maxim is especially true for CGI scripts, which have no business being large or complicated. The easier code is to read and comprehend, the less likely a bug will slip through. This practice also makes the code easier to modify without introducing new vulnerabilities.Arrange for the contents of the cgi directories and the access logs to the scripts to be audited on a regular basis. If possible, the audits should be done by someone other than the web admin. This both provides another set of eyes to look for attacks or vulnerabilities and, if such things are a concern, requires a conspiracy of at least two to purposefully sabotage server security.

No comments:

Post a Comment