Imagine that you have a guestbook script/handler, which works fine.
But you've forgotten about a small nuance: you
don't check the size of the submitted message. A 10
MB core file copied and pasted into the HTML
textarea entry box intended for a
guest's message and submitted to the server will
make the server grow by at least 10 MB. (Not to mention the horrible
experience users will go through when trying to view the guest book,
since the contents of the binary core file will be displayed.) If
your server is short of memory, after a few more submissions like
this one it will start swapping, and it may be on its way to crashing
once all the swap memory is exhausted.
To prevent such a thing from happening, you could check the size of
the submitted argument, like this:
my $r = shift;
my %args = $r->args;
my $message = exists $args{message} ? $args{message} : '';
die "the message is too big"
unless length $message > 8192; # 8KB
While this prevents your program from adding huge inputs into the
guest book, the size of the process will grow anyway, since you have
allowed the code to process the submitted form's
data. The only way to really protect your server from accepting huge
inputs is not to read data above some preset limit. However, you
cannot safely rely on the Content-Length header,
since that can easily be spoofed.
You don't have to worry about GET
requests, since their data is submitted via the query string of the
URI, which has a hard limit of about 8 KB.
Think about disabling file uploads if you don't use
them. Remember that a user can always write an HTML form from scratch
and submit it to your program for processing, which makes it easy to
submit huge files. If you don't limit the size of
the form input, even if your program rejects the faulty input, the
data will be read in by the server and the process will grow as a
result. Here is a simple example that will readily accept anything
submitted by the form, including fields that you
didn't create, which a malicious user may have added
by mangling the original form:
use CGI;
my $q = CGI->new;
my %args = map {$_ => $q->param($_)} $q->params;
If you are using CGI.pm, you can set the maximum
allowed POSTsize and disable file uploads using
the following setting:
use CGI;
$CGI::POST_MAX = 1048576; # max 1MB allowed
$CGI::DISABLE_UPLOADS = 1; # disable file uploads
The above setting will reject all submitted forms whose total size
exceeds 1 MB. Only non-file upload inputs will be processed.
If you are using the Apache::Request module, you
can disable file uploads and limit the maximum
POSTsize by passing the appropriate arguments to
the new( ) function. The following example has the
same effect as the CGI.pm example shown above:
my $apr = Apache::Request->new($r,
POST_MAX => 1048576,
DISABLE_UPLOADS => 1
);
Another alternative is to use the LimitRequestBody
directive in httpd.conf to limit the size of the
request body. This directive can be set per-server, per-directory,
per-file, or per-location. The default value is 0, which means
unlimited. As an example, to limit the size of the request body to 2
MB, you should add:
LimitRequestBody 2097152
The value is set in bytes (2097152 bytes = = 2 MB).