http://qs1969.pair.com?node_id=299599

JayBee has asked for the wisdom of the Perl Monks concerning the following question:

I am trying to upload files to my virtual server hosted with ipowerweb. I tried calling on two different scripts (not at the same time). One I copied online and the other from a book. They both work ok, as in the file appears as it was named, except that the file is blank, zero bytes, no content! What can I do to see it write the file properly?
#MAIN HTML start# <FORM ENCTYPE="multipart/form-data" ACTION="upload.pl" METHOD="get"> <p>Please select a file to upload: <br /> <INPUT TYPE="FILE" NAME="file"> <p><INPUT TYPE="submit"></FORM>'; #MAIN HTML end# here's my action file... ######FIRST ATTEMPT########################## ##HEADER## $dir = "tempfolder"; $file = param('file'); $file=~m/^.*(\\|\/)(.*)/; $name = $2; open(LOCAL, ">$dir/$name") or die $!; while(<$name>) { print LOCAL $_; } print 'Succeeded in your upload'; ######END########################### ######SECOND PROG.########################### ##HEADER## $dir = "tempfolder"; $file = param('file'); if ($file =~ /.*[\/\\](.*)/) { $out_file = $1; } else { $out_file = $file; } $counter = 0; while (-e "$dir/$out_file") { $counter++; $out_file =~ s/^(.+)\.(.+)$/$1$counter\.$2/; } print "$file<br />\n"; open (OFILE, "> $dir/$out_file"); while ($bytesread = read ($file, $buffer, 1024)) { print OFILE $buffer; } close $file; close OFILE; print 'Succeeded in your upload'; ######END###########################
Thanks for your help

Replies are listed 'Best First'.
Re: Uploading a file
by JayBee (Scribe) on Oct 16, 2003 at 01:02 UTC
    :) This actually works if I use "POST" instead of "GET". Since we are on the subject. Is there a good way to make this more secure or is it good enough? I plan to use it for pictures with extentions JPG, JPEG, and GIF. Could those type of files be dangerous to upload or display? Thanks agian. ...JayBee
      There are a few issues here. The biggest is that you are accepting someone elses name for the file you will be storing. If they give you a deliberately wrong filename they could overwrite important files on your system. Never allow a user to write to any old filename! Have your script pick the filename to save to, then save the users filename (description) in another file, or a database or something.

      You also have the potential to have your images cut off halfway through if the maximum POST size is set too small in your webserver.

      Also your script doesn't appear to have any sort of log in feature, so a naughty user could just upload thousands of files and fill up your server, and you wouldn't be able to stop them.

      ____________________
      Jeremy
      I didn't believe in evil until I dated it.

        It is acceptable to use the uploaded file name if the input is validated sufficiently. First is removing characters that could cause problems for the shell. This will prevent attacks against the shell and also help with giving file names that don't encoding or special processing. Also good is using the three argument form of open.
        my $path = File::Spec->catfile($dir, $file); open(OUT, '>', $path) or die;

        Another check is to remove any directory components. This prevents writing to files elsewhere on the filesystem. It guarantees that the files go in the right directory.

        It is a good idea to separate uploaded files into their own directory. If there is some authentication to control who can upload, then overriding an existing file isn't a security hole.