This is my upload accept script that is part of a larger app.
I am having problems with the session, and Taint. The script saves the file all good.. it just.. something is off on saving the session , which will record the file uploaded, just a string in a hash.
The error I get is ;
Insecure dependency in sysopen while running with -T switch at /usr/lib/perl5/site_perl/5.8.3/CGI/Session/Driver/file.pm line 63., referer: https://devel.internal/file.cgi?session=5b64b9342c0d1412333a3864fc28d223
The script is..
use CGI;
use CGI::Session;
use Data::Dumper;
use DMS::Files::Upload;
# init dms without normal checkihng,.. this is a problem with cgi validate and an upload, hack
my $DMS = load_nouser(conf=>'/srv/www/htdocs-devel/dms/conf/dms.conf');
#init cgi
my $cgi = new CGI;
for ($cgi->param()){ /^session$|^user_file$/ or die("bad field"); } # some minor checking .. make sure no extraneous data send
$$DMS{S}{session} = $cgi->param('session'); $$DMS{S}{session}=~m/^\w{32}$/ or die("no sid [$$DMS{S}{session}] or not 32 word chars");
# maybe the problem is in not untainting the session id or the session directory?
$$DMS{s} = new CGI::Session("driver:File",$$DMS{S}{session},{ Directory=> $$DMS{CONF}{SESSIONS_DIR} });
$ENV{REMOTE_ADDR} or die ('no ip');
$ENV{REMOTE_ADDR} eq $$DMS{s}->param('_SESSION_REMOTE_ADDR') or die("bad ip");
$$DMS{u}{userdir} = $$DMS{CONF}{DOC_USERS}.'/'.$$DMS{s}->param('user');
print STDERR "userdir $$DMS{u}{userdir}";
$$DMS{u}{logfile} = $$DMS{u}{userdir}.'/'.$$DMS{s}->param('user').'.log';
$$DMS{Q} = $$DMS{s}->param('Q');
# get some form stuff
$$DMS{upload}{filename} = $cgi->param('user_file');
my $data = $cgi->upload('user_file');
#untaint some stuff
if ($$DMS{u}{userdir}=~m/^([\/_\@\w .-]+)$/){ $$DMS{u}{userdir}=$1;} else {die("cant untaint userdir $$DMS{u}{userdir}\n");}
if ($$DMS{upload}{filename}=~m/^([\/_,\@\w .-]+)$/){ $$DMS{upload}{filename}=$1;} else {die("cant untaint name $$DMS{upload}{filename}\n");}
# should filename change because file alreaduy exists?
$$DMS{upload}{filename} = savename($$DMS{u}{userdir},$$DMS{upload}{filename}); #change name if file already exists.
$$DMS{upload}{destination} = "$$DMS{u}{userdir}/$$DMS{upload}{filename}";
userlog($DMS,'about to save upload');
DMS::Files::Upload::saveupload($DMS,$data) or die("cant save upload");
$$DMS{upload}{docfilepath}=$$DMS{upload}{destination}; $$DMS{upload}{docfilepath}=~s/^$$DMS{CONF}{DOC}\/// or die ($$DMS{upload}{docfilepath}." not in DMS_CONF_DOC=$$DMS{CONF}{DOC}");
$$DMS{upload}{docfilepath}=~s/\/\//\//g;
# place in Q
$$DMS{Q}{$$DMS{upload}{docfilepath}}=1;
$$DMS{s}->param('Q',$$DMS{Q});
$$DMS{s}->flush;
#print "Content-type: text/html\n\n";
print "Location: $$DMS{CONF}{WWW}/file.cgi?session=$$DMS{S}{session}\n\n";
#print Dumper($DMS);
exit;
Should I be untainting $$DMS{S}{session}, or $$DMS{CONF}{SESSIONS_DIR} ? is that the problem? I can access the session data just fine. Maybe I need to untaint the string I am recording to the session?
Any feedback appreciated. Thank you.
update: I was being a retard.. The session id and the session directory on server needed to be untainted, not for reading, but for writing. duh. so.. I added this:
#......y $DMS = load_nouser(conf=>'/srv/www/htdocs-devel/dms/conf/dms.conf');
#init cgi
my $cgi = new CGI;
for ($cgi->param()){ /^session$|^user_file$/ or die("bad field"); } # some minor checking .. make sure no extraneous data send
$$DMS{S}{session} = $cgi->param('session'); $$DMS{S}{session}=~m/^\w{32}$/ or die("no sid [$$DMS{S}{session}] or not 32 word chars");
#################################################################
# I WAS BEING A RETARD: these needed to be untainted... :)
if ($$DMS{S}{session}=~m/(^\w+$)/){
$$DMS{S}{session}=$1;
} else {die $!;}
if ($$DMS{CONF}{SESSIONS_DIR}=~m/^([\/\w -]+)$/){
$$DMS{CONF}{SESSIONS_DIR}=$1;
} else {die $!;}
##############################################################
# you dont need to untaint to read, but to write, yes, to the session file
$$DMS{s} = new CGI::Session("driver:File",$$DMS{S}{session},{ Directory=> $$DMS{CONF}{SESSIONS_DIR} });
$ENV{REMOTE_ADDR} or die ('no ip');
$ENV{REMOTE_ADDR} eq $$DMS{s}->param('_SESSION_REMOTE_ADDR') or die("bad ip");
# ......
Now it's happy :).
perlmonks.org content © perlmonks.org and leocharre
prlmnks.org © 2006 edmund von der burg (eccles & toad)
v 0.03