Issue with filepath name, possible corrupt charact

2019-08-27 15:47发布

问题:

Perl and html, CGI on Linux. Issue with file path name, being passed in a form field, to a CGI on server. The issue is with the Linux file path, not the PC side.

I am using 2 programs, 1) program written years ago, dynamic html generated in a perl program, and presented to the user as a form. I modified by inserting the needed code to allow a the user to select a file from their PC, to be placed on the Linux machine.

Because this program already knew the filepath, needed on the linux side, I pass this filepath in a hidden form field, to program 2.

2) CGI program on Linux side, to run when form on (1) is posted.

Strange issue. The filepath that I pass, has a very strange issue. I can extract it using

my $filepath = $query->param("serverfpath");

The above does populate $filepath with what looks like exactly the correct path.
But it fails, and not in a way that takes me to the file open error block, but such that the call to the CGI script gives an error.

However, if I populate $filepath with EXACTLY the same string, via hard coding it, it works, and my file successfully uploads.

For example:

$fpath1 = $query->param("serverfpath");
$fpath2 = "/opt/webhost/ims/DOCURVC/data" 

A comparison of $fpath1 and $fpath2 reveals that they are exactly equal. A length check of $fpath1 and $fpath2 reveals that they are exactly the same length.

I have tried many methods of cleaning the data in $fpath1. I chomp it. I remove any non standard characters.

$fpath1  =~ s/[^A-Za-z0-9\-\.\/]//g;

and this:

my $safe_filepath_characters = "a-zA-Z0-9_.-/";
$fpath1 =~ s/[^$safe_filepath_characters]//g;

But no matter what I do, using $fpath1 causes an error, using $fpath2 works.

What could be wrong with the data in the $fpath1, that would cause it to successfully compare to $fpath2, yet not be equal, visually look exactly equal, show as having the exact same length, but not work the same?

For the below file open block.

$upload_dir = $fpath1 

causes complete failure of CGI to load, as if it can not find the CGI (which I know is sometimes caused by syntax error in the CGI script).

$uplaod_dir = $fpath2   

I get a successful file upload

$uplaod_dir = ""        

The call to the cgi does not fail, it executes the else block of the below if, as expected.

here is the file open block:

if (open ( UPLOADFILE, ">$upload_dir/$filename" ))   
{
binmode UPLOADFILE;

while ( <$upload_filehandle> )
{
print UPLOADFILE;
}

close UPLOADFILE;
$msgstr="Done with Upload: upload_dir=$upload_dir filename=$filename";
}
else
{
$msgstr="ERROR opening for upload: upload_dir=$upload_dir filename=$filename";
}

What other tests should I be performing on $fpath1, to find out why it does not work the same as its hard-coded equivalent $fpath2

I did try character replacement, a single character at a time, from $fpath2 to $fpath1. Even doing this with a single character, caused $fpath1 to have the same error as $fpath2, although the character looked exactly the same.

回答1:

Is your CGI perhaps running perl with the -T (taint mode) switch (e.g., #!/usr/bin/perl -T)? If so, any value coming from untrusted sources (such as user input, URIs, and form fields) is not allowed to be used in system operations, such as open, until it has been untainted by using a regex capture. Note that using s/// to modify it in-place will not untaint the value.

$fpath1  =~ /^([A-Za-z0-9\-\.\/]*)$/;
$fpath1 = $1;
die "Illegal character in fpath1" unless defined $fpath1;

should work if taint mode is your issue.



回答2:

But it fails, and not in a way that takes me to the file open error block, but such that the call to the CGI script gives an error.

Premature end of script headers? Try running the CGI from the command line:

perl your_upload_script.cgi serverfpath=/opt/webhost/ims/DOCURVC/data