Perl
  Home arrow Perl arrow Page 2 - Writing Secure CGI Scripts
Dev Shed Forums 
Administration  
AJAX  
Apache  
BrainDump  
DHTML  
Flash  
Java  
JavaScript  
Multimedia  
MySQL  
Oracle  
Perl  
PHP  
Practices  
Python  
Reviews  
Security  
Style-Sheets  
Web Services  
XML  
Zend  
Zope  
Forums Sitemap 
IBM® developerWorks 
Sun Developer Network 
Dedicated Servers 
E-Commerce Hosting 
Linux Web Hosting 
Managed Hosting 
Small Business Hosting 
Actuate Whitepapers 
Moblin 
VPS Hosting 
Weekly Newsletter

 
Developer Updates  
Free Website Content 
IBM developerWorks
 RSS  Articles
 RSS  Forums
 RSS  All Feeds
Write For Us Get Paid 
Request Media Kit
Contact Us 
Site Map 
Privacy Policy 
Support 
 USERNAME
 
 PASSWORD
 
 
  >>> SIGN UP!  
  Lost Password? 
PERL

Writing Secure CGI Scripts
By: Pete Smith
  • Search For More Articles!
  • Disclaimer
  • Author Terms
  • Rating: 4 stars4 stars4 stars4 stars4 stars / 6
    2002-05-30

    Table of Contents:
  • Writing Secure CGI Scripts
  • Why should I care about security?
  • Shell processing
  • Untainting data

  • Rate this Article: Poor Best 
      ADD THIS ARTICLE TO:
      Del.ici.ous Digg
      Blink Simpy
      Google Spurl
      Y! MyWeb Furl
    Email Me Similar Content When Posted
    Add Developer Shed Article Feed To Your Site
    Email Article To Friend
    Print Version Of Article
    PDF Version Of Article
     
     
    ADVERTISEMENT

    Be the architects of evolution and help create the mobile internet future. It’s your move---enter to win here!

    Writing Secure CGI Scripts - Why should I care about security?


    (Page 2 of 4 )

    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:

    #!/usr/bin/perl -w

    use CGI;
    $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";

    close MAIL;

    print "Content-type:text/html\n\n";
    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="pete@perlcoders.com">
    <input type="submit">
    </form>


    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.

    More Perl Articles
    More By Pete Smith


     

       

    PERL ARTICLES

    - Perl: More on Lists and Hashes
    - Perl: Dimensional Lists
    - Perl: A Continuing Look at Hashes and Multid...
    - Perl: Another Round with Hashes
    - Perl Hashes
    - Perl Lists: A Final Look at List::Util
    - Perl Lists: Utilizing List::Util
    - Perl Lists: The Split() Function
    - SQL and CGI with Perl and DBI
    - Perl Lists: More Functions and Operators
    - SELECT Queries and Perl
    - Perl Lists: More on Manipulation
    - Creating a Database with Perl and DBI
    - Perl: Sailing the List(less) Seas
    - Perl and DBI




    © 2003-2008 by Developer Shed. All rights reserved. DS Cluster 2 hosted by Hostway