Commit 562cd9a4 authored by Dietmar Maurer's avatar Dietmar Maurer

improve security by setting size limits

parent 72c3bf16
...@@ -27,8 +27,9 @@ use HTTP::Status qw(:constants); ...@@ -27,8 +27,9 @@ use HTTP::Status qw(:constants);
use HTTP::Headers; use HTTP::Headers;
use HTTP::Response; use HTTP::Response;
# fixme my $limit_max_headers = 30;
# POST_MAX = 1024 * 10; # max 10K posts my $limit_max_header_size = 8*1024;
my $limit_max_post = 16*1024;
use Data::Dumper; # fixme: remove use Data::Dumper; # fixme: remove
...@@ -564,11 +565,12 @@ sub file_upload_multipart { ...@@ -564,11 +565,12 @@ sub file_upload_multipart {
if ($hdl->{rbuf} =~ s/^(.*?)\015?\012(--\Q$boundary\E(--)? \015?\012(.*))$/$2/xs) { if ($hdl->{rbuf} =~ s/^(.*?)\015?\012(--\Q$boundary\E(--)? \015?\012(.*))$/$2/xs) {
my ($rest, $eof) = ($1, $3); my ($rest, $eof) = ($1, $3);
my $len = length($rest); my $len = length($rest);
if ($len < 1024) { # fixme: max data size $rstate->{post_size} += $len;
if ($rstate->{post_size} < $limit_max_post) {
$rstate->{params}->{$rstate->{fieldname}} = $rest; $rstate->{params}->{$rstate->{fieldname}} = $rest;
$rstate->{phase} = $eof ? 100 : 0; $rstate->{phase} = $eof ? 100 : 0;
} else { } else {
syslog('err', "for data to large - abort upload"); syslog('err', "form data to large - abort upload");
$rstate->{phase} = -1; # skip $rstate->{phase} = -1; # skip
} }
} }
...@@ -644,13 +646,16 @@ sub get_upload_filename { ...@@ -644,13 +646,16 @@ sub get_upload_filename {
sub unshift_read_header { sub unshift_read_header {
my ($self, $reqstate, $state) = @_; my ($self, $reqstate, $state) = @_;
$state = {} if !$state; $state = { size => 0, count => 0 } if !$state;
$reqstate->{hdl}->unshift_read(line => sub { $reqstate->{hdl}->unshift_read(line => sub {
my ($hdl, $line) = @_; my ($hdl, $line) = @_;
eval { eval {
#print "$$: got header: $line\n"; # print "$$: got header: $line\n" if $self->{debug};
die "to many http header lines\n" if ++$state->{count} >= $limit_max_headers;
die "http header too large\n" if ($state->{size} += length($line)) >= $limit_max_header_size;
my $r = $reqstate->{request}; my $r = $reqstate->{request};
if ($line eq '') { if ($line eq '') {
...@@ -761,6 +766,7 @@ sub unshift_read_header { ...@@ -761,6 +766,7 @@ sub unshift_read_header {
params => decode_urlencoded($r->url->query()), params => decode_urlencoded($r->url->query()),
phase => 0, phase => 0,
read => 0, read => 0,
post_size => 0,
starttime => [gettimeofday], starttime => [gettimeofday],
outfh => $outfh, outfh => $outfh,
}; };
...@@ -769,6 +775,11 @@ sub unshift_read_header { ...@@ -769,6 +775,11 @@ sub unshift_read_header {
return; return;
} }
if ($len > $limit_max_post) {
$self->error($reqstate, 501, "for data too large");
return;
}
if (!$ct || $ct eq 'application/x-www-form-urlencoded') { if (!$ct || $ct eq 'application/x-www-form-urlencoded') {
$reqstate->{hdl}->unshift_read(chunk => $len, sub { $reqstate->{hdl}->unshift_read(chunk => $len, sub {
my ($hdl, $data) = @_; my ($hdl, $data) = @_;
...@@ -804,7 +815,7 @@ sub push_request_header { ...@@ -804,7 +815,7 @@ sub push_request_header {
my ($hdl, $line) = @_; my ($hdl, $line) = @_;
eval { eval {
#print "got request header: $line\n"; # print "got request header: $line\n" if $self->{debug};
$reqstate->{keep_alive}--; $reqstate->{keep_alive}--;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment