Ron Smith
Jul 11 2005, 11:22 AM
Hi all,
I'm back again with another question. And, thanks for your previous help. This time I'm working my wat through the book "Writing CGI applications with Perl". There's a tutorial that I've done that involves uploading a file and inserting the file name and description in MySQL. Some of you may be familiar with this one. Anyway, I get an error on the upload part when "-T" is used: #!/www/perl/bin/perl -wT. When it's removed, guess what? No error.
I would like to know if anyone on the list can take a look at the following script, and maybe explain why this happens. The error points to line 42. There's no explaination in the book of course.
TIA
Ron
Software error:
Insecure dependency in open while running with -T switch at C:/www/cgi-bin/upload_save.cgi line 42.
For help, please send mail to the webmaster (admin@localhost), giving this error message and the time and date of the error.
----------------snip-----------
#!/www/perl/bin/perl -wT
use strict;
use DBI;
use File::Basename;
use CGI qw(:standard);
use CGI::Carp qw(fatalsToBrowser);
my $directory = "C:/www/webroot/storage";
my $url_path = "/storage";
my $file_name = param('filename');
my $description = param('description');
my $file = Get_File_Name($file_name);
$CGI::POST_MAX = 1024 * 250; # limit uploads to 250kb
Store_Results();
Store_Description();
Print_Results();
sub Store_Description{
my $dbh = DBI->connect("DBI:mysql:book","geeksatlarge");
my $sth_insert = $dbh->prepare(qq{insert into files (Description,FileName) values (?,?)}) or die $dbh->errstr;
$sth_insert->execute($description,$file);
$dbh->disconnect;
}
sub Get_File_Name{
if ($ENV{HTTP_USER_AGENT} =~ /win/i) {
fileparse_set_fstype("MSDOS");
}
elsif ($ENV{HTTP_USER_AGENT} =~ /MAC/i) {
fileparse_set_fstype("MacOS");
}
my $full_name = shift;
$full_name = basename($full_name);
$full_name =~ s!s!_!g;
return($full_name);
}
sub Store_Results{
my $data;
my $mime = uploadInfo($file_name)->{'Content-Type'};
open (STORAGE, ">$directory/$file") or die "Error: $directory/$file: $!n"; # line 42<======
if ($mime !~ /text/) {
binmode ($file_name);
binmode (STORAGE);
}
while (read($file_name, $data, 1024)) {
print STORAGE $data;
}
close STORAGE;
}
sub Print_Results{
my $link = "$url_path/$file";
print header;
print start_html('File Upload And Save');
print <<HEREDOC;
<pre>
<b>File Sent: </b>$file_name
<b>File Name: </b>$file
<b>Link to File: </b><a href="$link">$link</a>
<a href="/cgi-bin/viewfiles.cgi">View Files</a>
</pre>
HEREDOC
print end_html;
}
----------------snip-----------
Chris Devers
Jul 11 2005, 06:32 PM
On Mon, 11 Jul 2005, Ron Smith wrote:
QUOTE |
Insecure dependency in open while running with -T switch at C:/www/cgi-bin/upload_save.cgi line 42.
|
What do you see on line 42?
It seems to be in Store_Results():
QUOTE |
sub Store_Results{ my $data; my $mime = uploadInfo($file_name)->{'Content-Type'}; open (STORAGE, ">$directory/$file") or die "Error: $directory/$file: $!n"; # line 42<====== if ($mime !~ /text/) { binmode ($file_name); binmode (STORAGE); } while (read($file_name, $data, 1024)) { print STORAGE $data; } close STORAGE; }
|
In other words, it chokes when you try to write to the dynamically
selected file, $directory/$file.
Unfortunately, this is exactly the sort of thing that taint mode is
supposed to be catching. Read the perldoc on it for details:
QUOTE |
From the command line, if available:
|
$ perldoc perlsec
Or read it from perldoc.perl.org:
<http://perldoc.perl.org/perlsec.html>
Hope this helps clarify things.
* ** *** ***** ******* *********** ************* *****************
On an entirely unrelated note, if you get in the habit of consistently
indenting your code now, you'll be *much* happier a year or five from
now when you're trying to maintain code you wrote when you started out.
A good indenting style -- the details of how you choose to indent don't
matter nearly as much as the fact that you do so consistently -- should
make the structure of your code much easier to grasp at a glance. Here's
how I might have written the subroutine in question:
sub Store_Results{
my ( $file_name, $directory, $file ) = @_;
my $data;
my $mime = uploadInfo($file_name)->{'Content-Type'};
open (STORAGE, ">$directory/$file")
or die "Error: $directory/$file: $!n"; line 42<======
if ($mime !~ /text/) {
binmode ($file_name);
binmode (STORAGE);
}
while (read($file_name, $data, 1024)) {
print STORAGE $data;
}
close STORAGE;
}
Note also that I explicitly pulled in arguments, rather than using
globals. This will mean changing the sub call to
Store_Results( $file_name, $directory, $file );
but writing it that way will also just serve to clarify things and make
it easier to maintain the program when you look at it again years later.
* ** *** ***** ******* *********** ************* *****************
You don't have to follow the details of how I'm doing this if you don't
want to, but at least choose some conventions and stick to them. Doing
so will, I promise, save you headaches in the long run :-)
--
Chris Devers
Ron Smith
Jul 12 2005, 01:39 PM
--- Chris Devers <[Email Removed]> wrote:
QUOTE |
On Mon, 11 Jul 2005, Ron Smith wrote:
Insecure dependency in open while running with -T switch at C:/www/cgi-bin/upload_save.cgi line 42.
What do you see on line 42?
It seems to be in Store_Results():
sub Store_Results{ my $data; my $mime = uploadInfo($file_name)->{'Content-Type'}; open (STORAGE, ">$directory/$file") or die "Error: $directory/$file: $!n"; # line 42<====== if ($mime !~ /text/) { binmode ($file_name); binmode (STORAGE); } while (read($file_name, $data, 1024)) { print STORAGE $data; } close STORAGE; }
In other words, it chokes when you try to write to the dynamically selected file, $directory/$file.
Unfortunately, this is exactly the sort of thing that taint mode is supposed to be catching. Read the perldoc on it for details:
From the command line, if available:
$ perldoc perlsec
Or read it from perldoc.perl.org:
<http://perldoc.perl.org/perlsec.html
Hope this helps clarify things.
* ** *** ***** ******* *********** ************* *****************
On an entirely unrelated note, if you get in the habit of consistently indenting your code now, you'll be *much* happier a year or five from now when you're trying to maintain code you wrote when you started out.
|
I agree and have taken your advice. I've also turned
off "color and graphics" in my messages, so I can post
replies where needed, instead of top posting. :-)
QUOTE |
Here's how I might have written the subroutine in question:
sub Store_Results{ my ( $file_name, $directory, $file ) = @_; my $data; my $mime = uploadInfo($file_name)->{'Content-Type'}; open (STORAGE, ">$directory/$file") or die "Error: $directory/$file: $!n"; line 42<====== if ($mime !~ /text/) { binmode ($file_name); binmode (STORAGE); } while (read($file_name, $data, 1024)) { print STORAGE $data; } close STORAGE; }
Note also that I explicitly pulled in arguments, rather than using globals. This will mean changing the sub call to
Store_Results( $file_name, $directory, $file );
but writing it that way will also just serve to clarify things and make it easier to maintain the program when you look at it again years later.
|
I also took you suggestion here too. I does make
things more clear and understandable.
I still get the error with the -T switch though, so
I'll check out the suggested reading.
Thanks Chris
Ron
QUOTE |
* ** *** ***** ******* *********** ************* *****************
You don't have to follow the details of how I'm doing this if you don't want to, but at least choose some conventions and stick to them. Doing so will, I promise, save you headaches in the long run :-)
-- Chris Devers
|