1) What harm can a cracker do?
As mentioned earlier, insecure CGI puts you and your web server at risk. Frequently, exploits are found in CGI scripts which will email any file on your system to the cracker - this could be credit card details, password files etc.
If a Unix server is compromised, the only guaranteed fix is to reinstall everything from disk. This obviously results in downtime and a lot of hard work for the administrator - don't be surprised if they take legal action against you as well.
2) I run a web server on my home computer. Only a few friends know it exists, so it will be safe.
Unfortunately, not true. Often crackers will scan entire ranges of IP addresses looking for vulnerable machines. Security through obscurity is not a solution.
3) Why would anyone want to crack my website? I don't have any enemies.
Your buggy CGI script which you thought nobody would care about could well turn out to be a stepping stone on the way to exploiting the web sever. A cracker may not care about your website, but he will certainly care about getting his hands on a fast Unix box.
4) I hear so much about security holes in Unix, luckily my hosting company use Windows NT.
Oh dear. The NT + IIS combination has a notoriously bad track record. NT's only advantage is that it's second-rate networking and lack of proper multi-user support makes it less attractive to crackers.
5) I only use well-known paid/free CGI scripts. Surely these are safe?
Again, not necessarily. Many famous CGI scripts have bugs in them - some have huge gaping holes. Matt's FormMail script is one such example, although I must stress that the bug was fixed in subsequent versions. Still, I've seen many web providers actually recommending the buggy version in their help pages. We'll come back to the FormMail script a little later – it's a classic examples of flawed CGI security in action.
Hopefully by now you realise the importance of secure CGI (if you did not already). In the remaining sections of this article we'll look at some common holes and how to patch them.
The Golden Rule of CGI
Never, ever, ever trust user input - this is the key behind writing secure CGI, so chant it like a mantra until it is firmly in your head. Whether accidentally or intentionally, unexpected user input can cause all sorts of havoc in your scripts.
Consider the following simple script for sending email:
$q= new CGI;
$from = $q->param('from');
$to = $q->param('to');
$subject = $q->param('subject');
$message = $q->param('message');
open MAIL, "| /usr/bin/sendmail -t" || die "Coudlnt open sendmail: $!";
print MAIL "To: $to\n";
print MAIL "From: $from\n";
print MAIL "Subject: $subject\n\n";
print MAIL "$body";
print "Thank you, your message has been sent";
This is a rough idea of how the script might work, based on an HTML form like this:
<form action="emailme.pl" method="post">
Your Email Address<input type="text" name="from">
Subject <input type="text" name="subject">
Message <input type="text" name="message">
<input type="hidden" name="to" value="email@example.com">
Basic, but you get the general picture: a visitor enters his name and a message. The message then gets emailed onto you. Do you see the problem in the script above? If not, read through it again (it's flawed thinking, not an actual programming error).
The problem is the hidden input field in the form. At first glance it seems to make sense to set an email address in the form. If your email address changes, or you want to give copies of the script to your friends, it is a lot easier to edit a html field that it is to edit a CGI script.
But that's forgetting our golden rule: never trust user input. All the cunning cracker has to do is view the source code of your HTML page and copy/paste it into his own HTML page. He can then change the email address in the form to anything he likes. Next, he loads his modified copy of the form in his web browser, fills in an unpleasant message and sends it to someone he doesn't like. The email gets send via your web server, and the recipient will automatically assume it came from you.
Now this alone might not be too bad, but with the aid of some CGI scripting the process can be automated allowing millions of emails to be sent via your script. A spammer's dreams come true, and unless you can prove otherwise, you'll end up getting the blame.
The solution is simple enough: rather than having the hidden form field, add a line to the top of the script such as:
$to = "pete\@perlcoders.com";
..and delete the $to = $q->param('to') line. (Remember to escape the @ by using a backslash).
Simple, and we've potentially saved us a lot of trouble. So simple in fact that you may be surprised to learn that a very popular site offering free CGI scripts actually made this mistake. Lots of people who should have known better (including web hosting companies and web designers) still use this script.
It should be noted that the bug was fixed in subsequent versions of the script.
If problems like that don't bother you, then read on for more CGI horrors.
blog comments powered by Disqus