7.9 CGI Security Considerations

Although CGI programming is not inherently insecure, insecure CGI programs are easy to write. In this section, we discuss some of the most common security issues with CGI programs. If you heed these suggestions, you will be a long way toward being secure, or at least you will not be an easy target.

7.9.1 Avoid Shipped and Downloaded CGI Programs

We mentioned this before in Chapter 3, but it deserves mention again: Do not trust preshipped CGIs. Before developing your own CGI scripts, remove all the ones you find in cgi-bin , or if you want to keep them around, change their permissions so that they are not executable.

And never download CGI programs from source code web sites. Many contain serious security problems. Besides, now that you know how to write them, you don't need to download them. Why should you deprive yourself of the fun of writing them yourself? At the very least, be very sure you understand what any CGI script you download does, in detail, before you use it.

7.9.2 Never Assume Anything

It is very easy for a savvy cracker (or a not so savvy script kiddy, for that matter) to pass to your CGI program fields that you did not expect. As an example, this script executes the nameage.cgi script and passes it an unexpected field: [6]

[6] The code may look a bit complex to you, but we bet you could figure out how to take its content and modify it a bit to abuse your favorite CGI program. But we know you would not do this maliciously. We certainly don't suggest you do it.

 #! /usr/bin/perl  use HTTP::Request::Common POST;  use LWP::UserAgent;  use strict;  my $ua = LWP::UserAgent->new();  my $req = POST http://www.opensourcewebbook.com/cgi-bin/nameage.cgi,              [ yourname => John Doe, age => 95, baddata => gotcha ];  my $content = $ua->request($req)->as_string;  print $content; 

The bogus field name "baddata" is sent with the bogus data "gotcha." Easy to do, and done all the time. [7] Don't assume that you get only what you expect.

[7] In the example, sending this data to nameage.cgi is not a big deal, because it is essentially ignored; but you can see how easy it would be to send bogus posted data to a CGI program.

7.9.3 Always Check Data, Including the Length

To quote a former president, "Trust, but verify." He was speaking of the former USSR and nuclear weapons, but the philosophy is the same. The Cold War now is between you and crackers. To deal with the reality that you should never trust what you receive, always verify what you have. For instance, if you expect a valid first name, you should verify that you get one:

 if ($firstname =~ /  ^  [\w\. ]+$/) {      # all is well  } else {      # there is a problem  } 

This regular expression checks to see if $firstname contains only word characters ( [a-zA-Z0-9_] ), spaces, or periods. No other characters are allowed.

Checking the length of the data is a snap:

 $name = param(name)  John Doe;  if (length($name) > 60) {      # someone is being nasty  } 

7.9.4 Never Trust Hidden Fields

This distrust of what you receive applies to hidden fields as well. Let's say that a form to purchase a new pair of shoes has the name of the shoes and the price of the shoes in hidden fields:

 <input type="name" price="NewShoes">  <input type="hidden" price="149.00"> 

A cracker (or someone who wants a deal on a new pair of shoes, and don't we all?) could post the price as:

 $req = POST http://www.example.com/cgi-bin/checkout.cgi,           [ price => 0.00, name => NewShoes ]; 

Now that is a good price! [8]

[8] A similar scam has been worked on PayPal even though this kind of exploit is extremely well known.

One of the most common exploits in practice today, and not just of CGI scripts, is buffer overflows. If you write a CGI program that expects a name, you might write that name to a database (see Chapter 5). If someone were to send you 50MB of data for a name, putting that data in the database would use excessive amounts of disk space or worse . A number of exploits of many different programs have relied on buffer overflows to start their nastiness. Programmers of every stripe must learn to check input data for reasonable lengths in every application ”don't be lazy. Do it not just in this application, but everyplace in this book where you accept data from the outside world.

7.9.5 Don't Trust Filenames

The trust issue is magnified many times when it comes to filenames. Never trust data you receive if you are using data to open files. A classic example is that of "magic opens" ”for example, a remote mail reader that does an open MAIL, "/var/mail/$USERNAME". This sort of thing has caused many exploits because of applications opening attachments, as you probably know.

7.9.6 Don't Trust Referer Headers

The referer information is sent in through the header. The header can be constructed to be whatever the evil person wants, so don't trust it. Referer information is useful when you want to know from whence a user is coming, but don't put too much trust into it.

7.9.7 Don't Trust Cookies or JavaScript Preprocessing

Cookies are small tokens of information that reside on the client computer and send information back to the server. Examples are the cookie that remembers your password for the New York Times and the cookie that tells Amazon who you are so that you can get back to the half-finished order you started yesterday ”very convenient , but also powerful and insecure.

Because they are sent in the header, they can be constructed to be whatever a less than honorable person wants. Don't trust them completely. On the server side, always double-check cookie information.

JavaScript preprocessing of data is nice, but don't assume it has taken place. Always check your data.

Be Paranoid . That says it all. If you are going to put your server out in the big bad world and accept bits from the madding crowds, don't blindly accept what they send you. Be cautious, be paranoid, and expect to not think of everything. Check your logs. Watch the skies!

Open Source Development with Lamp
Open Source Development with LAMP: Using Linux, Apache, MySQL, Perl, and PHP
ISBN: 020177061X
EAN: 2147483647
Year: 2002
Pages: 136

Similar book on Amazon

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net