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

I made a script for people to upload a file to a server from the internet. The script takes a file, renames it to epoch seconds that correlates to its upload time and stores it in an web inaccessable directory on a webserver eg /upload.

How big is the risk of someone exploiting this script to hack the server? Particularly I'm worried about someone inserting some code into the file that the CPU would execute. Or put "../../../../../etc/passwd" in the file that would capatilize on the "open" or similar command.

I was thinking maybe I should PGP encrypt this file on the server. I'm also making a partition on the server that will just have "upload" data on it; to stop Denial of Service attacks (by filling up my hard drive).

How can I make this more secure? How can this be comprimised?

Here's my code:

#!/usr/bin/perl -w use strict; use CGI; my $upload_dir = "/upload"; my $query = new CGI; my $filename = $query->param("filename"); my $uldate = time; $filename =~ s/.*[\/\\](.*)/$1/; my $upload_filehandle = $query->upload("filename"); open UPLOADFILE, ">$upload_dir/$uldate"; binmode UPLOADFILE; while ( <$upload_filehandle> ) { print UPLOADFILE; } close UPLOADFILE; exit;

Replies are listed 'Best First'.
Re: File Upload Script: Security Issue???
by Xaositect (Friar) on Jun 28, 2005 at 21:16 UTC
Re: File Upload Script: Security Issue???
by gellyfish (Monsignor) on Jun 28, 2005 at 21:04 UTC

    There is generally no direct risk from the content of the file until you try to open it with in a particular application that some mailcious person may have targetted with some carefully crafted file - on windows you might want to take the precaution of either removing the suffix or supplying a (for example) .safe if there is a danger of random people opening the files. I would also alter the sanitizing of the filename to something like:

    $filename =~ /([^\/\\]*)$/; $filename = $1;
    Of course you aren't actually using the name of the file so all of the above doesn't apply to your code.

    You might consider setting $CGI::POST_MAX to a sensible value to avoid a DoS through a massive upload and you probably also want to use the -T flag to turn tainting on so you can't do anything silly in the perl program with the user supplied input. Other than that you are safe from any over risks.

    /J\

Re: File Upload Script: Security Issue???
by hubb0r (Pilgrim) on Jun 28, 2005 at 21:01 UTC
    I guess that it really depends on what happens with these files AFTER they have been uploaded. It doesn't matter at all what is in the file that is being uploaded... It will never be executed in your code. Unless you are at some point exec()'ing the contents of the file (ps. NEVER NEVER NEVER exec use supplied data!) then the contents of the file will stay just as they are: the contents of the file.

    If somehow the file was being placed into a portion of the web server that WAS accessible, and the file was executable, then you would have a different story on your hands, but you did say that it would be stored in a non-accessible directory as well.

    Given what you've told us so far, you appear to be safe as written.
      People are going to download the file by referencing its filename indirectly (using it upload date in epoch seconds): i.e. get.cgi?id=xxxxxxx

      The server then takes it's id, looks up it's proper filename in a DB, then sends the file to the browser.

      Here's the relevant part of my download script:

      open(DLFILE, "<$file_location/$id") || Error('open', 'file'); @fileholder = <DLFILE>; close (DLFILE) || Error ('close', 'file'); print "Content-Type:application/x-download\n"; print "Content-Disposition:attachment;filename=@filename[0]\n\n"; print @fileholder

        Hi,

        Don't use something like a epoch, because what happens if you have 2 person uploading... epoch only give you a second accuracy, so I would give them a temporary filename, take a look a File::Temp. Or if you want a next step you can think about giving a filename based on the md5sum of the input file or something else.

        Regards,

        :-)
Re: File Upload Script: Security Issue???
by cmeyer (Pilgrim) on Jun 28, 2005 at 21:12 UTC

    Consider using the three argument form of open. This will prevent the user from including characters in filename that can effect what open() does (e.g. '-' or a numerical file descriptor).

    -Colin.

    WHITEPAGES.COM | INC