X-Git-Url: http://git.freeside.biz/gitweb/?a=blobdiff_plain;f=rt%2Fbin%2Fwebmux.pl.in;h=5c09e65b94fa11fc109ca885dfb09bd051728a9f;hb=0eab7643459bbf8626b0e89240d2f5f9d8a957d8;hp=8086177afdddcec560e0ec4d75acee7032fc1857;hpb=fc6209f398899f0211cfcedeb81a3cd65e04a941;p=freeside.git diff --git a/rt/bin/webmux.pl.in b/rt/bin/webmux.pl.in index 8086177af..5c09e65b9 100644 --- a/rt/bin/webmux.pl.in +++ b/rt/bin/webmux.pl.in @@ -3,7 +3,7 @@ # # COPYRIGHT: # -# This software is Copyright (c) 1996-2011 Best Practical Solutions, LLC +# This software is Copyright (c) 1996-2013 Best Practical Solutions, LLC # # # (Except where explicitly superseded by other copyright notices) @@ -60,23 +60,25 @@ package RT::Mason; our ($Nobody, $SystemUser, $Handler, $r); -my $protect_fd; +my $protect_fds; sub handler { ($r) = @_; - if ( !$protect_fd && $ENV{'MOD_PERL'} && exists $ENV{'MOD_PERL_API_VERSION'} - && $ENV{'MOD_PERL_API_VERSION'} >= 2 && fileno(STDOUT) != 1 + if ( !$protect_fds && $ENV{'MOD_PERL'} && exists $ENV{'MOD_PERL_API_VERSION'} + && $ENV{'MOD_PERL_API_VERSION'} >= 2 ) { - # under mod_perl2, STDOUT gets closed and re-opened, however new STDOUT - # is not on FD #1. In this case next IO operation will occupy this FD - # and make all system() and open "|-" dangerouse, for example DBI - # can get this FD for DB connection and system() call will close - # by putting grabage into the socket - open $protect_fd, '>/dev/null' or die "Couldn't open /dev/null: $!"; - unless ( fileno($protect_fd) == 1 ) { - warn "We opened /dev/null to protect FD #1, but descriptor #1 is already occupied"; - } + # under mod_perl2, STDIN and STDOUT get closed and re-opened, + # however they are not on FD 0 and 1. In this case, the next + # socket that gets opened will occupy one of these FDs, and make + # all system() and open "|-" calls dangerous; for example, the + # DBI handle can get this FD, which later system() calls will + # close by putting garbage into the socket. + $protect_fds = []; + push @{$protect_fds}, IO::Handle->new_from_fd(0, "r") + if fileno(STDIN) != 0; + push @{$protect_fds}, IO::Handle->new_from_fd(1, "w") + if fileno(STDOUT) != 1; } local $SIG{__WARN__}; @@ -93,6 +95,20 @@ sub handler { RT::ConnectToDatabase(); + # none of the methods in $r gives us the information we want (most + # canonicalize /foo/../bar to /bar which is exactly what we want to avoid) + my (undef, $requested) = split ' ', $r->the_request, 3; + my $uri = URI->new("http://".$r->hostname.$requested); + my $path = URI::Escape::uri_unescape($uri->path); + + ## Each environment has its own way of handling .. and so on in paths, + ## so RT consistently forbids such paths. + if ( $path =~ m{/\.} ) { + $RT::Logger->crit("Invalid request for ".$path." aborting"); + RT::Interface::Web::Handler->CleanupRequest(); + return 400; + } + my (%session, $status); { local $@;