]> git.proxmox.com Git - pve-http-server.git/blobdiff - src/PVE/APIServer/AnyEvent.pm
requests: assert that theres no @ in the URLs authority
[pve-http-server.git] / src / PVE / APIServer / AnyEvent.pm
index 24b2002879f1585d1dfbb985d3015553e193d25a..9de623815b2ddfea50a7647e87e51005cc668ff7 100644 (file)
@@ -702,10 +702,20 @@ sub proxy_request {
     eval {
        my $target;
        my $keep_alive = 1;
+
+       # stringify URI object and verify it starts with a slash
+       $uri = "$uri";
+       if ($uri !~ m@^/@) {
+           $self->error($reqstate, 400, "invalid proxy uri");
+           return;
+       }
+
+       my $may_stream_file;
        if ($host eq 'localhost') {
            $target = "http://$host:85$uri";
            # keep alive for localhost is not worth (connection setup is about 0.2ms)
            $keep_alive = 0;
+           $may_stream_file = 1;
        } elsif (Net::IP::ip_is_ipv6($host)) {
            $target = "https://[$host]:8006$uri";
        } else {
@@ -791,6 +801,10 @@ sub proxy_request {
                        $header->header(Location => $location);
                    }
                    if ($stream) {
+                       if (!$may_stream_file) {
+                           $self->error($reqstate, 403, 'streaming denied');
+                           return;
+                       }
                        sysopen(my $fh, "$stream", O_NONBLOCK | O_RDONLY)
                            or die "open stream path '$stream' for forwarding failed: $!\n";
                        my $resp = HTTP::Response->new($code, $msg, $header, undef);
@@ -1560,6 +1574,11 @@ sub push_request_header {
                        $self->error($reqstate, 506, "http protocol version $maj.$min not supported");
                        return;
                    }
+                   if ($url =~ m|^[^/]*@|) {
+                       # if an '@' comes before the first slash proxy forwarding might consider
+                       # the frist part of the url to be part of an authority...
+                       $self->error($reqstate, 400, "invalid url");
+                   }
 
                    $self->{request_count}++; # only count valid request headers
                    if ($self->{request_count} >= $self->{max_requests}) {