From f3257881315192e7ed2ef8f424cafaa0d726eb7b Mon Sep 17 00:00:00 2001 From: Thomas Lamprecht Date: Fri, 1 Jul 2022 11:32:54 +0200 Subject: [PATCH] response: avoid linefeeds in response status 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 Reported-by: STAR Labs --- src/PVE/APIServer/AnyEvent.pm | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/src/PVE/APIServer/AnyEvent.pm b/src/PVE/APIServer/AnyEvent.pm index 7a8b9ad..223309e 100644 --- a/src/PVE/APIServer/AnyEvent.pm +++ b/src/PVE/APIServer/AnyEvent.pm @@ -288,9 +288,16 @@ sub response { my $code = $resp->code; my $msg = $resp->message || HTTP::Status::status_message($code); - ($msg) = $msg =~m/^(.*)$/m; 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 = "";