As I clearly state in my Site Security Page,
you are the biggest threat to your own site! The odds of damage
occuring due to a malicious attack are quite smaller than your chances
of doing something to upset the balance of life in your server.
Drawing on both my own experience (yep, I've blown up a few boxes in
my time), and the advice of others, here are some tips to help make
your life both simpler and safer.
NEVER RUN YOUR SERVER AS ROOT
In the land of Unix, god is a four letter word, root. Do
not under any circumstances allow your web server to run as root.
Let me clarify this. Do not run your web server as root. Just in
case you missed this point, do not run your web server as root.
While you are at it, do not let your web server run as any
user with administrative priviledges, such as lp, bin, daemon.
Also, make certain that your web server is in a group of its
own, and not a member of any user or administrative group.
Why is this so important? Because I said so! In all seriousness,
if somebody exploits a flaw in a script running with root's
permissions that allows them to
write to files, they can very quickly either gain access to your
system or just plain trash it.
If the web server can only write to files that it needs to, the
damage can be limited to only those files. Okay, maybe your
web pages will be damaged, but it is much easier to recover
those files from a backup copy than it is to re-install your
operating system. Which brings me to my next point...
MAKE SYSTEM BACKUPS A REGULAR PART OF YOUR DAY
As obvious as this sounds, many people do not make weekly
backups, let alone daily ones. If you have your server close
at hand, use tape. If you don't, use tape and try to arrange
for somebody to swap tapes for you.
If making tape backups is inpractical, or if you want extra
insurance, here is a trick that will save you both bandwidth
and time.
One of the beautiful things about unix is that to it, everything
is a file- including you. What this means is that you can use
the tar (tape archive) program to create a file on disk
that you can then FTP to another server. Using an FTP client to
copy hundreds or thousands of small files is very inefficient,
but you can package things into what is called a tarball
and move it very quickly.
If all of your website files are located in /usr/local/apache/share
(as an example), you can do the following:
- Use telnet to log into your site.
- Issue the command:
tar cvf myfiles010198.tar /usr/local/apache/share
When it finishes running, compress the file with
gzip myfiles010198.tar
- You will now have a file called myfiles010198.tar.gz that
you can FTP down to your PC. You can even open the file using
Winzip!
ALWAYS BACKUP ANY FILE BEFORE MAKING CHANGES
Probably the single biggest threat to your site is the following
scenario. It's late in the evening and you decide that since
traffic is light that it would be a great time to make some
changes to your configuration files. You edit away, restart
your server and nothing happens. The system is running, but
you are getting either no pages or error messages.
The site has now been down for almost five minutes and you are
starting to get nervous. You go and look at each file that you
think you changed, but you are not certain as to what was
originally there. The site has now been down over fifteen minutes
and nervousness is giving way to panic. You now go to your
backup tape and one by one, start restoring files. Of course,
this particular set of files is located at the end of a 3GB
tape.... Two hours later, you are back up and running again.
You can avoid this problem very easily. If you are editing
httpd.conf, first make a copy of it. In unix, just give the
command:
cp httpd.conf httpd.conf.bak
If you have a problem, all you have to do is issue the command
again with the file names reversed.
cp httpd.conf.bak httpd.conf
This is the cheapest insurance you can possibly buy.
NEVER USE SERVER SIDE INCLUDES WITH USER GENERATED PAGES
If you are using a guestbook or virtual card script that allows
users to enter HTML, it is critical that you do not allow these
pages to be parsed by the server. I have tried to execute system
commands using includes and have been successful at doing so.
Here are some tips:
- Do not use the .shtml extension for files that are either
created by, or appended to by user input.
- Make certain that your script removes the HTML Comment tags
from user input. In perl, this works:
$somevariable =~ s/<!--(.|\n)*-->//g;
- If you want to be extra careful, place all such files in
a directory that has an .htaccess file forbidding server
site includes.
Options NONE
- Disable SSI direct program execution. Instead of using
an exec directive, use the virtual one.
In your .htaccess file or in your access.conf file,
use:
Options Includes IncludesNOEXEC
DO NOT PASS UNCHECKED CGI INPUT TO THE UNIX COMMAND LINE
One of the more common causes of security breaches is running a
script that performs a unix command without first checking for
unix metacharacters and such in the input.
Even better, try to pipe
user input to a program rather than using it as a command line
argument.
Here is a classic example of the worst case scenario.
You have a mail response form on your site. Your web server just
also happens to be running as root. A malicious reader provides
the following e-mail address:
nobody@home.com;/bin/rm -fr /[c-z]*
If you look at the source code, you will notice that I have
a # (unix comment character) embedded in an HTML comment tag.
Just typing that command gives me the willies....
Instead of calling sendmail using the "-t" option and piping the
information to it, you use the command line method. Here is what
happens next.
The ; character tells unix that a new line has begun. Guess
what comes after the ; mark? The command that removes all the files
that really matter to the server. If this were to happen to your
server, it would require a complete reinstallation of the operating
system.
Here is an example of how to trap for illegal characters in a
domain name lookup script (whois):
if ($fields{domname}=~ /^([-\@\w.]+)$/) {
$fields{domname} = $1;
$result= `$whois_program $fields{domname}`;
print $result;
} else {
print "Illegal Character(s) sent...";
}
DO NOT ALLOW OFFSITE EXECUTION OF YOUR CGI SCRIPTS
One problem with many form handling scripts is that the webmaster
neglects to control where they are called from. This can allow a
user to change variable names, and otherwise try to interfere with
the orderly execution of things. A very simple way to prevent this
is to take advantage of the CGI environment variable,
HTTP_REFERER. This variable contains the name of the URL that called
the script. If the user edits the form and executes it from his
computer, this value will be blank, or have the URL of where he
is running it from if it is saved as a page on another server.
Here is a little snippet of perl to place at the top of a script
to prevent such a thing from happening:
@okaydomains=("http://bignosebird.com",
"http://www.bignosebird.com");
$DOMAIN_OK=0;
$RF=$ENV{'HTTP_REFERER'};
$RF=~tr/A-Z/a-z/;
foreach $ts (@okaydomains)
{
if ($RF =~ /$ts/) { $DOMAIN_OK=1; }
}
if ( $DOMAIN_OK == 0)
{ print "Content-type: text/html\n\n Sorry...";
exit;
}
Of course, you have to use your domain name! In the example above
notice that the list of valid domains is lowercase. The program
changes any uppercase characters to lower case so you don't have
to worry about things like, "www.BigNoseBird.com".
CHECK ALL SCRIPTS CAREFULLY BEFORE EXECUTING THEM
After downloading a script from any site, always try to read
through the code to try and find any suspicious commands. Also,
be sure to change any default file names for logs and the like
to prevent people that know the script from accessing them by
name on your server.
WATCH YOUR LOGS FOR SUSPICIOUS ACTIVITIES
Get to know both your unix system logs as well as your APACHE
server logs. Keeping an eye on these can alert you well ahead
of time to a potential problem. Look for things such as invalid
login attempts and other warnings in your logs.
Despite movies to the contrary, hackers seldom get in on the
first try. There is not much you can do about a true professional,
but you do have a good chance of dealing with a hacker wannabe.
SOMETHING ONLY YOU KNOW IS A SECRET...
But of course, once you tell somebody else, it is public information.
Don't e-mail passwords, grant server access to people you do not know,
and do not announce to the world how you protect your site.
You want to know what I do in terms of intrusion detection and
security? I could tell you, but then I would have to kill you. ;-)
OTHER GOOD SOURCES FOR SECURITY INFORMATION
There are a lot of good security sites on the net, but also be
sure to visit the vendor of your operating system to check
for advisories.
Of course, APACHE is the best place to
find current information on web server security issues.
I also recommend CERT Coordination Center
at Carnegie Mellon. They provide a great deal of information on both
preventative measures, as well as what to do if you are attacked.
The W3C Security Resources Page
is another excellent reference resource.