Beefy Boxes and Bandwidth Generously Provided by pair Networks
The stupid question is the question not asked

Thoughts on file upload...

by mojobozo (Monk)
on Nov 20, 2002 at 14:56 UTC ( #214468=perlquestion: print w/replies, xml ) Need Help??
mojobozo has asked for the wisdom of the Perl Monks concerning the following question:

My fellow perlaholics,

Recently (today, in fact), I finished with my file upload script. I didn't do it on my own and have a few monks to thank for their assistance (Mr. Muskrat, jdporter, and a couple others whose names escape me at the moment). Although I have a working script that does what I want it to, it still needs to be cleaned up as I would like it to be easier to read and have fewer lines. But, that is not why I am writing this.

The real reason for this node is for some advice. I have written into it a section that alters the name of the file uploaded and another that will only allow certain TYPES of files to be uploaded (thanks to jdporter on that one... he didn't give me the answer, but his help led me to write my own). I do both of these things for security reasons. My big question: Is there anything else I should consider adding to the script to furthur the security?

Thanks for your time,
word (wrd)
interj. Slang. Used to express approval or an affirmative response to
something. Sometimes used with up. Source

Replies are listed 'Best First'.
Re: Thoughts on file upload...
by mikeirw (Pilgrim) on Nov 20, 2002 at 15:20 UTC

    Not really security related per se, but I think that it's wise to set a maximum file size that you'll accept so that someone doesn't try to fill up your disk.

    You can do this easily (if you're using with something like:

    # Limit file sizes to 1 MB use constant MAX_FILE_SIZE => 1_048_576; $CGI::POST_MAX = MAX_FILE_SIZE;

    You may also want to set a size limit on the directory that is holding the uploaded files. This could be done with something like:

    # 100 MB limit on the size of the upload dir use constant MAX_DIR_SIZE => 100 * 1_048_576; sub dir_size { my $dir = shift; my $dir_size = 0; my $file; # Loop through files and sum the sizes; doesn't descend down subdi +rs. opendir DIR, $dir or die "Unable to open $dir: $!\n"; $dir_size += -s "$dir/$file" while defined( $file = readdir DIR ); closedir DIR; return $dir_size; } die 'Upload directory is full.' if ( dir_size('/path/to/dir') + $ENV{CONTENT_LENGTH} > MAX_DIR_SIZE +);
Re: Thoughts on file upload...
by AcidHawk (Vicar) on Nov 20, 2002 at 15:12 UTC

    I can't really speak as I have not looked at you script, but have you thought about a username/password validation to upload..?

    I am constintaly being asked to implement this.

    Of all the things I've lost in my life, its my mind I miss the most.
      The script is already in an area that is password protected and on top of that only certain users are allowed access to it. To top it off, it's on a secure intranet.
      word (wrd)
      interj. Slang. Used to express approval or an affirmative response to
      something. Sometimes used with up. Source
Re: Thoughts on file upload...
by rob_au (Abbot) on Nov 20, 2002 at 21:22 UTC
    It might be worth having a look at my CGI::Upload module - This module provides methods to securely handle return uploaded files and return pertinent information such as uploaded fule name and file types as returned by both file extension and file MIME types (see the link to File::MMagic elsewhere in this thread).

    The sort of "rule based" upload of files which you seek is something which I am working on for a new module called CGI::Upload::Rule, fashioned very much after the File::Find::Rule module.


    perl -e 'print+unpack("N",pack("B32","00000000000000000000000111101001")),"\n"'

Re: Thoughts on file upload...
by Jaap (Curate) on Nov 20, 2002 at 15:51 UTC
    Post your code and we might find some caveats... i am especially curious how you implemented the file type checking.
      A snippet:
      my %file_ok = qw{ .gif 1 .jpg 1 .htm 1 .html 1 .txt 1 .doc 1 .pdf 1 }; and then.... ($base,$path,$type) = fileparse($file,'\..*'); and finally... $type =~ tr/A-Z/a-z/; if (!$file_ok{$type}) { print "The type of file you tried to upload ($type) is not sup +ported."; return; }
      how's that?
      UPDATE: Added the line to make the extension lowercase as some losers in my industry love CAP LOCK.
      word (wrd)
      interj. Slang. Used to express approval or an affirmative response to
      something. Sometimes used with up. Source

        I would not trust file extensions; File::MMagic seems to me a better solution; here is an untested snippet:

        use File::MMagic; $mm = new File::MMagic; # use internal magic file # disable checks made against file extension $mm->removeFileExts; $type = $mm->checktype_filename("/somewhere/unknown/file"); ...

        $type will contain a MIME mediatype string.

        HTH, Valerio

Log In?

What's my password?
Create A New User
Node Status?
node history
Node Type: perlquestion [id://214468]
Approved by newrisedesigns
and all is quiet...

How do I use this? | Other CB clients
Other Users?
Others having an uproarious good time at the Monastery: (5)
As of 2018-01-24 10:45 GMT
Find Nodes?
    Voting Booth?
    How did you see in the new year?

    Results (257 votes). Check out past polls.