brayshakes has asked for the wisdom of the Perl Monks concerning the following question:

I'm learning Perl in hopes of writing CGI scripts and am beginning to feel the paranoia about security. What are common security measures implemented into Perl? Are outside functions used? SSL? Whats the skinny?

Replies are listed 'Best First'.
Re: Curiosity and Security
by graff (Chancellor) on Jan 24, 2007 at 04:31 UTC
    Zaxo's advice is solid, but the perlsec man page is deeply detailed and includes discussion of other issues that are not relevant to CGI and web scripting in general (e.g., you might get lost in the discussion of "setuid" and "setgid" scripts, which don't apply to what you want to do).

    In terms of giving you "the skinny" on "the big picture" (block that metaphore!), the basic primary piece of wisdom is: do not trust anything you get from the client who is sending you any sort of request.

    If you put up a page containing a form, and write a cgi script to process the parameters that can be posted by a client via that form, don't just assume that every request to your cgi script actually comes from that page, because someone can view your page source, and mechanize any sort of bot to pound your cgi script with all sorts of probing parameter values, especially if there's any conceivable incentive to do so.

    That's what "taint checking" is all about. Values coming from the client need to be checked to assure that they meet specific expectations. An adequate check might just be a matter of limiting the length of a string (for storage to a file or database field), or making sure a string consists of just digits, or matches one of a set of specific hash keys that are either hard-coded in your app or read in from a "trusted" source.

    Since it's usually hard to anticipate all the ways that a given process or input can go wrong, the general rule of thumb is for the taint-check logic to look specifically at the conditions that are necessary in order for something to be "right". If a given parameter value is expected to be extremely varied or complicated, make sure you don't try to do anything "risky" with that value -- don't use it as part of a shell command or sql statement. (Save it to a file, or use a placeholder in the sql statement and pass the value as a paramter when executing the sql.)

    I don't think it will help much to say any more, until you show us some code that you're thinking of using.

Re: Curiosity and Security
by Zaxo (Archbishop) on Jan 24, 2007 at 02:54 UTC

    Run perldoc perlsec or just follow that link for a solid overview.

    After Compline,
    Zaxo

Re: Curiosity and Security
by SheridanCat (Pilgrim) on Jan 24, 2007 at 04:05 UTC
    If you intend to do any work with databases, you should also read up on protecting your code from SQL injection. Here's a starting place: Avoiding SQL Injection Attacks.
Re: Curiosity and Security
by holli (Abbot) on Jan 24, 2007 at 08:57 UTC
Re: Curiosity and Security
by rinceWind (Monsignor) on Jan 24, 2007 at 09:14 UTC

    Don't forget Ovid's CGI course.

    --

    Oh Lord, won’t you burn me a Knoppix CD ?
    My friends all rate Windows, I must disagree.
    Your powers of persuasion will set them all free,
    So oh Lord, won’t you burn me a Knoppix CD ?
    (Missquoting Janis Joplin)

Re: Curiosity and Security
by EvanK (Chaplain) on Jan 24, 2007 at 16:14 UTC
    Mostly seconding the points driven home by other monks, but:
    • use taint checking
    • use strict and use warnings
    • use taint checking
    • NEVER run apache or a CGI script as root or with suid (suexec is a whole other discussion, however)
    • use taint checking
    In case you couldn't tell, the biggest point if security is your top priority (and when is it not?) is to use taint checking :)

    __________
    The trouble with having an open mind, of course, is that people will insist on coming along and trying to put things in it.
    - Terry Pratchett

Re: Curiosity and Security
by ptum (Priest) on Jan 24, 2007 at 21:19 UTC

    One basic principle to follow is to never trust anything from the browser that you can look up elsewhere with more confidence. Imagine a shopping cart application, in which a user browses through items for sale and adds them to his cart, finally checking out. If you store the price or shipping costs in the user's cart and trust those values blindly, you may find yourself selling items for a penny or even (if you're particulalry careless) paying customers to buy your stuff. Better to accept the minimum information from the user (perhaps an item-identifying number and a quantity) and re-calculate cost & shipping every time you need it.

    This is a rather simplistic example, but I think that the principle is sound -- never trust tainted data and be very careful about how you detaint it. Some folks use CGI::Session to help with this sort of thing.