Many security documents are already available for Perl, including the perlsec documentation and the security chapter in Programming Perl. This page details various security tips and tricks for Perl.
- Avoiding backticks in Perl - calling external programs without using unsafe backticks.
- Perl and Temporary Files - methods to properly handle temporary files.
Database Access
Databases may allow untrusted input to run. Solutions include taint checking all user input for problems, and using placeholders to avoid Structured Query Language (SQL) injection attacks. See the DBI Perl module documentation for additional pointers.
When using a transactional database, wrap read-only SELECT statements in a transaction, then rollback the transaction when done. Using this trick, even if an attacker inserts a malicious SQL statement, their changes will be undone when the transaction rolls back. The example code below uses the DBIx::Simple wrapper for DBI.
use DBIx::Simple ();
my $db = DBIx::Simple->connect("dbi:Pg:dbname=data");
…
sub select {
$db->begin_work;
my $data = $db->query(qq{SELECT * FROM test WHERE foo = $bar});
$db->rollback;
…
}
File Access
When opening a filename stored in a variable, unexpected behavior may result due to how the open
function parses that variable. The following code should print the contents of a file, though can be tricked into running and showing the output of arbitrary commands, as the second example shows:
$ perl -we '$f = shift; open F, "$f"; print while <F>' /etc/passwd
…
$ perl -we '$f = shift; open F, "$f"; print while <F>' 'ls /etc|'
…
To avoid this problem, always specify the redirection statement such as > before the variable, and include a space between the redirection statement and the variable containing the filename:
$ perl -we '$f = shift; open F, "< $f"; print while <F>' /etc/passwd
…
$ perl -we '$f = shift; open F, "< $f"; print while <F>' 'ls /etc/|'
readline() on closed filehandle F at -e line 1.
Modern versions of Perl have improved the open
function. If code will only run on newer versions of Perl (5.8 and above), always use the three-argument method:
open(my $fh, '<', $file) or die "error opening $file: $!\n";