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

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

If you've been working with CGI.pm for any length of time, you know that it allows uploads by default and does not have a maximum post size. Since it saves the uploads as a temp file, someone can simply upload enough data to fill up your hard drive to initiate a DOS attack. To prevent this, we're regularly warned to include the following two lines at the top of our CGI scripts:

$CGI::DISABLE_UPLOADS = 1; # Disable uploads $CGI::POST_MAX = 512 * 1024; # limit posts to 512K max

As long as those are their before you instantiate a CGI object (or before you access param and related CGI functions with the function oriented interface), you have pretty safely plugged this problem. However, most CGI scripts don't have these lines of code. Some suggest changing these settings directly in CGI.pm. I dislike this for two reasons:

  1. If you upgrade CGI.pm, you might forget to make the change to the new version.
  2. You may break a lot of existing code (which may or may not be a good thing depending upon the security implications).

So, my thought was to write a CGI::Safe module that inherits from CGI.pm. It will establish the defaults for those variables and require virtually no code changes. Further, no existing code would be affected. You can also override the defaults established by explicitly stating them in your code or passing them as named arguments to the CGI::Safe constructor. It would work like this:

use CGI::Safe; my $q = CGI::Safe->new( DISABLE_UPLOADS => 0 );

This would be equivalent to:

use CGI::Safe; $CGI::DISABLE_UPLOADS = 0; my $q = CGI::Safe->new;

Since you can also pass arguments to the CGI constructor, you would pass them like this:

my $q = CGI::Safe->new( data => $stuff );

Just a rough hack:

################################ package CGI::Safe; ################################ $VERSION = .1; use strict; use CGI; use vars qw/ @ISA /; @ISA = ( "CGI" ); INIT { # Establish some defaults $CGI::DISABLE_UPLOADS = 1; # Disable uploads $CGI::POST_MAX = 512 * 1024; # limit posts to 512K max } sub new { my ( $self, %args ) = @_; $CGI::DISABLE_UPLOADS = $args{ DISABLE_UPLOADS } if exists $args{ +DISABLE_UPLOADS }; $CGI::POST_MAX = $args{ POST_MAX } if exists $args{ +POST_MAX }; return ( exists $args{ data } ) ? CGI::new( $self, $args{ data } ) + : CGI::new( $self ); }

I'm wondering if anyone sees any problems with this approach or if anyone has any suggestions.

Cheers,
Ovid

Vote for paco!

Join the Perlmonks Setiathome Group or just click on the the link and check out our stats.