safe cgi programming in perl?

S

Steve

Hi all, please excuse the long post, but this is the longest perl
script I've ever written. My main concern is with untainting data and
using backtics for system commands. I read most of the documentation,
but confess the perlsec leaves me a little confused as to the best way
to write to files, etc.

I'm using -Tw on the shabang line, plus "use strict"

I threw this in, but I am not sure if it is neccessary:

$ENV{PATH} = "/bin:/usr/bin";
delete @ENV{ 'IFS', 'CDPATH', 'ENV', 'BASH_ENV' };

I'm only using mkdir, open and rm with user input.

Here's my untaint routines:

-------------------

if ($pairs{affilate_ID} =~ /^([-_\w.\s]+)$/) { $pairs{affilate_ID} =
$1 }
else { bad_data_in_affilate_ID () }
if ($pairs{general_theme} =~ /^([-_\w.\s]+)$/) { $pairs{general_theme}
= $1 }
else { bad_data_in_theme () }

my @untainted_keywords = split(/\, /, $pairs{keywords});

my $untainted_keyword;
for $untainted_keyword (@untainted_keywords) {
if ($untainted_keyword =~ /^([-_\w.\s]+)$/) { $untainted_keyword = $1
}
else { bad_data_in_keywords () }
}

-------------------

most of my commands to create directories, files and to remove files
are with backtics, and I've untainted all the data....so have I
covered all the bases or should I understand more about the perlsec
and shell vs system calls...esp this example:

use English '-no_match_vars';
die "Can't fork: $!" unless defined($pid = open(KID, "-|"));
if ($pid) { # parent
while (<KID>) {
# do something
}
close KID;
} else {
my @temp = ($EUID, $EGID);
my $orig_uid = $UID;
my $orig_gid = $GID;
$EUID = $UID;
$EGID = $GID;
# Drop privileges
$UID = $orig_uid;
$GID = $orig_gid;
# Make sure privs are really gone
($EUID, $EGID) = @temp;
die "Can't drop privileges"
unless $UID == $EUID && $GID eq $EGID;
$ENV{PATH} = "/bin:/usr/bin"; # Minimal PATH.
# Consider sanitizing the environment even more.
exec 'myprog', 'arg1', 'arg2'
or die "can't exec myprog: $!";
}

Thanks very much for any replys,

Steve
 
T

Tad McClellan

Steve said:
My main concern is with untainting data and
using backtics for system commands.
I'm only using mkdir,


Is that the shell's mkdir(1) or Perl's mkdir() function?



_That_ must be Perl's open(), I don't think there is a shell "open".

and rm with user input.


And that is clearly the shell's rm(1).

most of my commands to create directories, files and to remove files
are with backtics,


You can do all three of those things in native Perl rather than
"shelling out" to external programs.

perldoc -f mkdir
perldoc -f open
perldoc -f unlink


Avoiding a shell goes a long way toward peace of mind, so you
should avoid it whenever possible.

As an added bonus, you could then move your program unchanged
to some other operating system.
 
T

Tad McClellan

Steve said:
My main concern is with untainting data and
using backtics for system commands.

if ($pairs{affilate_ID} =~ /^([-_\w.\s]+)$/) { $pairs{affilate_ID} =
$1 }


Allowing dot may be dangerous, as it can have meta-meaning in a path.

What if

$pairs{affilate_ID} = '../etc/passwd';
$pairs{affilate_ID} = '../../etc/passwd';
$pairs{affilate_ID} = '../../../etc/passwd';

etc.

Do you allow users to enter relative paths?
 
S

Steve

Hi Ted,

Thank you for giving me some good suggestions. First off, I removed
the dot when untainting data.

I'm using a combination of Perl commands and backtics.

Perl:
mkdir, open

Shell:
zip, rm, mv, chmod

the problem I was having was in dealing with the cgi program creating
files with owner "apache". So I was having a hard time getting
"unlink" and "rmdir" to work.

But I think I will follow your advice and try moving more of the
backtic commands to perl commands.

Steve
 
N

news

Tad McClellan said:
Allowing dot may be dangerous, as it can have meta-meaning in a path.
What if
$pairs{affilate_ID} = '../etc/passwd';

But equally, one has to consider these:
$pairs{affilate_ID} = 'some.valid.file';
$pairs{affilate_ID} = '.../hiddenfile';

Chris
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,968
Messages
2,570,153
Members
46,699
Latest member
AnneRosen

Latest Threads

Top