The vast majority of scripts I write are CGI-related in some way. Naturally, I've found that placing a script online, where anyone can take a shot at it, can be a little unnerving at times. Luckily Perl eliminates many security problems (buffer overflows for one :), but there are still many areas of concern. I've attempted to list the essential security practices that, when followed, enable one to write more secure CGI scripts.

Taint Mode - I use this in every CGI script I write. It has helped me catch many mistakes that I would have otherwise overlooked. Sometimes though it gets me feeling a little too secure, as perlsec says "The tainting mechanism is intended to prevent stupid mistakes, not to remove the need for thought."

User Input - As a CGI Course I recently read stated "always trust your users. Never trust their input." Legitimate users can send unexpected data, malicious users will send everything you can think of - and more. This includes manipulating hidden form field values. Don't depend on the referrer (or "referer" ;) either, for it can be easily spoofed as well.

Also worthy of noting, when filtering user input don't try to think up every possible symbol/combination to filter out. Instead, simply state the form of the data your script will except and return an error for everything else.

Error Messages - Don't give out more information than necessary. If a user supplies an incorrect password for a legitimate user name, print out 'Incorrect Login' not 'Incorrect Password.' Also make sure to get all those use CGI::Carp qw/fatalsToBrowser/; out of production code.

Make %ENV safer - From perlsec "... set $ENV{'PATH'} to a known value, and each directory in the path must be non-writable by others than its owner and group." It also goes on to suggest that including something along the lines of delete %ENV{qw(IFS CDPATH ENV BATH_ENV)}; would be a good idea.

Encryption - Essential for any sensitive data. There are a whole bunch of modules on cpan dealing with encryption but currently I have very limited experience with them. Any advice from the more experienced monks on this subject would be appreciated.

Those are the essential security practices that I currently employ. Inevitably I have overlooked something so please reply with any suggestions for improving this node. Thanks.

In reply to Essential CGI Security Practices by cjf

Use:  <p> text here (a paragraph) </p>
and:  <code> code here </code>
to format your post; it's "PerlMonks-approved HTML":

  • Posts are HTML formatted. Put <p> </p> tags around your paragraphs. Put <code> </code> tags around your code and data!
  • Titles consisting of a single word are discouraged, and in most cases are disallowed outright.
  • Read Where should I post X? if you're not absolutely sure you're posting in the right place.
  • Please read these before you post! —
  • Posts may use any of the Perl Monks Approved HTML tags:
    a, abbr, b, big, blockquote, br, caption, center, col, colgroup, dd, del, div, dl, dt, em, font, h1, h2, h3, h4, h5, h6, hr, i, ins, li, ol, p, pre, readmore, small, span, spoiler, strike, strong, sub, sup, table, tbody, td, tfoot, th, thead, tr, tt, u, ul, wbr
  • You may need to use entities for some characters, as follows. (Exception: Within code tags, you can put the characters literally.)
            For:     Use:
    & &amp;
    < &lt;
    > &gt;
    [ &#91;
    ] &#93;
  • Link using PerlMonks shortcuts! What shortcuts can I use for linking?
  • See Writeup Formatting Tips and other pages linked from there for more info.