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.


In reply to Preventing DOS attacks with CGI.pm by Ovid

Title:
Use:  <p> text here (a paragraph) </p>
and:  <code> code here </code>
to format your post, it's "PerlMonks-approved HTML":



  • Posts are HTML formatted. Put <p> </p> tags around your paragraphs. Put <code> </code> tags around your code and data!
  • Titles consisting of a single word are discouraged, and in most cases are disallowed outright.
  • Read Where should I post X? if you're not absolutely sure you're posting in the right place.
  • Please read these before you post! —
  • Posts may use any of the Perl Monks Approved HTML tags:
    a, abbr, b, big, blockquote, br, caption, center, col, colgroup, dd, del, details, div, dl, dt, em, font, h1, h2, h3, h4, h5, h6, hr, i, ins, li, ol, p, pre, readmore, small, span, spoiler, strike, strong, sub, summary, sup, table, tbody, td, tfoot, th, thead, tr, tt, u, ul, wbr
  • You may need to use entities for some characters, as follows. (Exception: Within code tags, you can put the characters literally.)
            For:     Use:
    & &amp;
    < &lt;
    > &gt;
    [ &#91;
    ] &#93;
  • Link using PerlMonks shortcuts! What shortcuts can I use for linking?
  • See Writeup Formatting Tips and other pages linked from there for more info.