Please read the following advices before writing a CGI script.
If you have any question ask the software group by mail, phone or come to see us ... we don't bite ... :-)
1. Making secure script
- "eval" command in script CGI
If you plan to use Perl (or other scrip language) to program your CGI, be very careful when using the "eval" command with part of the user input as parameters. Intruders could use this security hole to execute remote shell command. Same things for the system command under perl or C.
- Command Interpreter
Never install a command interpreter in the cgi-bin directory. It's offer the capability to the world to execute the interpreter (like perl, tcl whatever ..) and make lot of dangerous things ...
- Compiled CGI vs. script CGI
Compiled CGI in C for exemple are more safer than Script files. It will only lower the risk of hole, but it's not a guarantor against hacker. So use compiled CGI if you can, but try to make it secure in the same way that for a script CGI.
- When using a CGI found on Internet
If you want to use a CGI found on the web, be very careful, think that maybe the programmer is an hacker, and want to intrude our system. So, always give a look on the script source before install it. If you have any doubt or you don't very familiar with CGI or the language used in the script, ask for help to the software group or to the script author. Anyway, be very suspicious ...
Always ask yourself this question :
- How complex is it? The longer it is, the more likely it is to have problems.
- Does it read or write files on the host system? Programs that read files may inadvertently violate access restrictions you've set up, or pass sensitive system information to hackers. Programs that write files have the potential to modify or damage documents, or, in the worst case, introduce trojan horses to your system.
- Does it interact with other programs on your system? For example, many CGI scripts send e-mail in response to a form input by opening up a connection with the sendmail program. Is it doing this in a safe way?
- Does it run with suid (set-user-id) privileges? In general this is a very dangerous thing and scripts need to have excellent reasons for doing this.
- Does the author validate user input from forms? Checking form input is a sign that the author is thinking about security issues.
- Does the author use explicit path names when invoking external programs? Relying on the PATH environment variable to resolve partial path names is a dangerous practice.
- Always keep in mind when you write your CGI :
- Avoid giving to mutch information about the site and web server host
- Be careful for the size of the user input (buffers overflow)
- Check all values provided by the user
- Never pass unchecked user input to a shell command or to an eval command
- Check all return codes from system calls
- Make consistency-checking of your internal variable (e.g. a variable which value could be 1,2 or 3 must not have the value 5)
- Make the critical code or our CGI as small and simple as possible
- Set yourself the current directory
- Limit script resource usage for avoiding the Denial-of-services Attacks
- Test your CGI thoroughly
- Environment variables
Don't use the environment variable PATH. It's could be change by hacker and execute another program than the one you want. This is the same things for other environment variables, be very careful when using them. If you need a PATH on your CGI specify it inside.
- Restrict acces inside the CGI
You not sure that your CGI will be executed with the correct form, so test each user input before doing something with. A crash of your CGI could be used as a security hole by an hacker .
- Hidden variable
Try to use hidden variable for unimportant stuff .. and always check the value of those variable before using it, even if you create it yourself. This kind of variable could be corrupted, and do bad things.
- Dump core
Program your CGI to avoid dumping Core. Core files could be very big and fill up the filesystem.
2. Secure Installation of script
- Permissions on the files and subdirectories need to be such that they are writable only by the maintainer of the script, or root. Never create world-writable directories or directories or files owned by "nobody" anywhere under /cgi-bin/. Don't create symlinks under cgi-bin pointing outside of cgi-bin either. World-writable files and directories can be identified by using ls -l and looking for permission letters that end in anything with ?w? instead of r-x or r--. Turn off writability with chmod a-w filename(s).
Log files and temp files
- Log files and temporary files should go in a subtree that is somewhere in /apps/www/server (and NOT anywhere under /apps/www/cfht/) If you have a log file in /cgi-bin/, a hacker could cause a command to get printed into your log file and then request the log file as a URL. Since it is in /cgi-bin/, the web server will attempt to execute the log file as a program, which could be trouble!
- As a general rule, if you find a random CGI script on the web, please change the name slightly before using it. This may sound silly, but people have robots that go from site to site just trying the names of cgi scripts with known security bugs.
Command Line Arguments
- I need to find a link to a page with a description of some common mistakes that allow people to sneak commands in by putting strange characters on the command line. Generally, C programs that use popen() or system() are dangerous, and you should have someone in software look it over first.
- Separate the CGI from the document tree.
- Make sur that no CGI will execute under the root account. There is no exception to this rule .. never never allow a script to run with root privilege. If you have any problems for accessing to data, ask the software group for help.
CGI-BIN directory check
- Always look in the cgi-bin directory after you modify or create a CGI for backup copy (Emacs for exemple create backup copy with a ~ at the end). If you found some backup file, erase it without remorse ...
Initial version by Sidik Isani last update by Jean-Louis Villecroze on the July 17th 1998.