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

Hello Monks,

I am setting up a small web ap using CGI. We are using it to keep track of updates and other tweaks to our applications.

What I want to do is upload images and word docs to our server using some small formatting. I have figured out how to do this. However the question is should I do this and what are some measures I can take to safeguard this.

I'm only allowing access to a certain group to read/write to the directory and have turned off all scripts inside of the dir that i'm writing to.

Here is the relevant code I have so far.

#! C:\perl\bin\perl -w use strict; use CGI; use CGI::Carp qw(fatalsToBrowser); use BKG::HTML::format; # Some Security Holes Plugged $CGI::POST_MAX = 100 * 1024 * 1024; # limit posts to 100M max my $q = new CGI; ################# # Get form data # ################# $T=1; $x=1; while ($T) { $test1 = "name_upfile" . $x; $test2 = "upfile" . $x; if (($q->param($test1)) and ($q->param($test2))) { $file_name[$x-1] = $q->param($test1); $file[$x-1] = $q->upload($test2) or die "test:$!"; $x++; } else { $T=0 } } mkdir "C:/web/aps/mi/$name", 0755 or die "Cannot make dir: $!"; $x=0; foreach (@file_name) { open (OUTFILE, ">C:/web/aps/mi/$name/$_") or die "Cannot open $nam +e: $!"; binmode(OUTFILE); while ($bytesread=read($file[$x],$buffer,1024)) { print OUTFILE $buffer; } close OUTFILE or die "Close:$!"; $x++; }

Any and all thoughts are welcome.

Replies are listed 'Best First'.
Re: Security Uploading Files
by Joost (Canon) on Apr 18, 2004 at 17:18 UTC
    Some random issues to watch out for:
    • If you can, make sure that only people you allow may upload (for instance, by requiring authentication via the server)
    • Make sure the file system doesn't fill up. You could for instance disable uploading if there's less than some amount of space on the disk (you probably should set this in a BEGIN block).
    • Disabling scripts in the data directory is not enough, if that dir is directly accessible via the server - people can upload php, asp, jsp pages (even server config files), or malicious client side scripts.
    • Watch out for malicious file names!
    • Use taint mode! (perl -wT) - in my view this should be mandatory for any CGI script.
    • As you are running on windows, use binmode on the data file handles.
      1. I am using the authentication in place by the server.
      2. Could you please point me in the right direction where I can look to see how to do this?
      3. I disabled the use of scripts in the web server itself and through the file system. Is this not enough?
      4. Good call forgot to do this.
      5. Everytime I turn on the taint switch I get the error:

      Too late for "-T" option at C:\web\...

      6. I am using binmode() on the filehandles. Am I not using them correctly.

      Also is there any way to check to see if a file is actually that type? e.g. .jpg is actually an image file or .doc is actually a word document? Thanks for the tips so far!

        In regards to checking the amount of disk space left, you may want to partition your hard drive so that files are uploaded on a separate partition. Then, even if someone manages to try to upload a terabyte of data from /dev/urandom, all that gets filled will be your partition, and your computer should still be able to operate.


        Want to support the EFF and FSF by buying cool stuff? Click here.
        The easiest way to check how much space is left, is probably to use "some commandline tool" (I use df, but that only works on UNIX).

        Depending on how you disable scripting, not everything might actually be turned off (i.e. in Apache, if you disable CGI scripts, you might still have PHP switched on, etc.) Just make sure you really turned it all off, or serve the files via another script.

        Taint mode in IIS (and maybe some other web servers) can AFAIK not be turned on via the shebang line, you probably need to switch it on in the server config somewhere (haven't done this in years, so I can't remember how exactly). If you turn it on in the server, scripts using perl -wT should run fine too.

        As for file types, not reliably. Check for extensions and mime-type, but people can always fake it. File::MimeInfo::Magic might be useful.

        edit: oh yes, I overlooked the binmode in your script. I think it's fine like that.

        Hope this helps.
        Joost.

Re: Security Uploading Files
by matija (Priest) on Apr 18, 2004 at 17:16 UTC
    Well, if I read your code correctly, you accept the output filename from the client. I think you should untaint the filename (make sure it doesn't contain any dangereous characters) - in particular, you might want to make sure the user couldn't put the file in a directory other than the one you intended for them.

    I don't recall right now if the ../ thing works for windows systems (like you appear to be using), but that's one of the things you might want to check for.

    You might also want to decide if overwriting the files already in the directory should be permitted or not. Currently, you don't check for that, so a file might be overwritten either by mistake or through malicious action.

      Will do on the overwrite checking!!