]> git.proxmox.com Git - pve-http-server.git/commitdiff
response: avoid linefeeds in response status
authorThomas Lamprecht <t.lamprecht@proxmox.com>
Fri, 1 Jul 2022 09:32:54 +0000 (11:32 +0200)
committerThomas Lamprecht <t.lamprecht@proxmox.com>
Fri, 1 Jul 2022 09:38:16 +0000 (11:38 +0200)
basically only possible to trigger with chromium based browsers
(chrome, edge, opera) but besides those having the biggest usage
currently its not that nice in any way.

Users could inject headers in their response, which isn't really that
bad itself, as they won't really do anything at least for sane
browsers that don't allow setting third party cookies by default
(unlike again, chrome), in which case one can create huge cookies
that then trigger the max header size check on requests, DOS'ing an
user's access to a PVE interface if they can get them to visit a
malicious site (a clear cooki actione would allow visiting it again)

Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
Reported-by: STAR Labs <info@starlabs.sg>
src/PVE/APIServer/AnyEvent.pm

index f5653e9be4d18717044055900ae1c57f6225f611..24b2002879f1585d1dfbb985d3015553e193d25a 100644 (file)
@@ -293,9 +293,16 @@ sub response {
 
     my $code = $resp->code;
     my $msg = $resp->message || HTTP::Status::status_message($code);
 
     my $code = $resp->code;
     my $msg = $resp->message || HTTP::Status::status_message($code);
-    ($msg) = $msg =~m/^(.*)$/m;
     my $content = $resp->content;
 
     my $content = $resp->content;
 
+    # multiline mode only checks \n for $, so explicitly check for any \n or \r afterwards
+    ($msg) = $msg =~ m/^(.*)$/m;
+    if ($msg =~ /[\r\n]/) {
+       $code = 400; # bad request from user
+       $msg = HTTP::Status::status_message($code);
+       $content = '';
+    }
+
     if ($code =~ /^(1\d\d|[23]04)$/) {
        # make sure informational, no content and not modified response send no content
        $content = "";
     if ($code =~ /^(1\d\d|[23]04)$/) {
        # make sure informational, no content and not modified response send no content
        $content = "";