CGI and Perl

Tools for Executing CGI Safely

If you're using Perl as your CGI scripting mechanism, there are a number of new tools and modules you can use to assure that your CGI scripts operate correctly and safely. These modules are consistently maintained and updated, and the authors are fully aware of all of the potential problems that face the Webmaster when introducing the CGI risk to his or her Web. We'll be introducing these tools and modules in Chapter 5, "Putting It All Together."


It's fairly trivial to write a Perl script to perform a specific task as a CGI if you're an experienced Perl programmer. So why bother learning how to use a specific module to perform a task if you can hack up something offhand? The risks of doing this probably are in proportion to the experience of the scriptor and his/her familiarity with the CGI-related risks, but in the long run, the added value of learning and using the appropriate module will definitely outweigh the bother of learning to use it. Hopefully, this will become evident to you as you read this tutorial.

The Safe module is relatively new to Perl5 but is already part of the default distribution. It provides you with the capability to create a "compartment" where only certain Perl operations can be executed. If a script attempts to execute an operation that is disallowed or hasn't been specifically allowed, the operation will be trapped, and the error will be found in $@, just as with eval(), looking something like

open trapped by operation mask

to indicate that the open() operator is not allowed within the compartment.

You might use the Safe module to create a compartment where the script can never execute a command that causes the UNIX shell to be invoked, for instance, by masking out the opcodes that correspond to system(), '' (backticks), exec(),fork(), and glob(). Masking these oper- ations is the default when creating a new Safe compartment.

The Safe module, as of Perl5.003, uses the Opcode module to set up its compartment and the masks for each of the opcodes that are considered unsafe in the typical insecure environment. The Opcode module relies on the fact that Perl code is compiled into an internal format before it is executed. Within this compiled internal format, is of the operations Perl can execute is reduced to a numerical value. If a mask has been put in place for any given operation's opcode, for instance, open(), the compilation will fail if the open() statement is found anywhere in the Perl code. The Opcode module is not usually used directly but should be understood by those who will be setting up Safe compartments.