diff --git a/HTTP-Daemon-6.01-CVE-2026-8450.patch b/HTTP-Daemon-6.01-CVE-2026-8450.patch new file mode 100644 index 0000000..6ead240 --- /dev/null +++ b/HTTP-Daemon-6.01-CVE-2026-8450.patch @@ -0,0 +1,113 @@ +From 241989d49b5aedcde4bfd2a5e8257ea2c2fd252b Mon Sep 17 00:00:00 2001 +From: Olaf Alders +Date: Thu, 14 May 2026 00:09:58 +0000 +Subject: [PATCH] Fix CVE-2026-8450: send_file() honoured 2-arg open() + shell-magic + +HTTP::Daemon::ClientConn::send_file() used the 2-arg form +open(FILE, $file), which interprets shell-magic prefixes in the +path argument: '| cmd' (write pipe -- RCE), 'cmd |' (read pipe -- +RCE plus response-body exfiltration via the sysread / print loop +below), '> path' (write-truncate -- arbitrary file write), and +'>> path', '+< path', '<&fd', and leading-whitespace variants of +the above. + +Any HTTP::Daemon-based application that passed attacker-influenced +bytes to send_file($string) -- for example, a download endpoint +that derived the filename from a query parameter -- granted command +execution and/or arbitrary file write at the daemon's UID. + +Switch to 3-arg open(my $fh, '<', $file): the explicit '<' mode +makes the path argument a literal filename, so every magic shape +above is opened (and fails, returning undef) as an ordinary file by +that exact name. The localized typeglob is no longer needed and is +replaced with a lexical filehandle. + +Two collateral hardening changes ride along: + + - binmode() failure now closes the handle and returns undef, + rather than streaming the file with a wrong PerlIO layer. + + - send_file() returns '0E0' (true zero) on a successful zero-byte + transfer so callers using "send_file or die" can distinguish + open failure (undef) from an empty-but-successful copy. + +The POD now documents the new return-value contract and spells +out that the fix only neutralises 2-arg open() shell-magic; +callers remain responsible for validating attacker-influenced +paths against symlinks, character/block devices (e.g. /dev/zero), +named pipes, and document-root escapes. + +Reported and patched by Stig Palmquist (stigtsp). + +Co-Authored-By: Claude Opus 4.7 +--- + lib/HTTP/Daemon.pm | 37 +++++++++++++++++++++++++++++++------ + 1 file changed, 31 insertions(+), 6 deletions(-) + +diff --git a/lib/HTTP/Daemon.pm b/lib/HTTP/Daemon.pm +index 216c73f..a715159 100644 +--- a/lib/HTTP/Daemon.pm ++++ b/lib/HTTP/Daemon.pm +@@ -617,12 +617,11 @@ sub send_file + { + my($self, $file) = @_; + my $opened = 0; +- local(*FILE); + if (!ref($file)) { +- open(FILE, $file) || return undef; +- binmode(FILE); +- $file = \*FILE; +- $opened++; ++ open(my $fh, '<', $file) || return undef; ++ binmode($fh) || do { close($fh); return undef }; ++ $file = $fh; ++ $opened++; + } + my $cnt = 0; + my $buf = ""; +@@ -633,7 +632,11 @@ sub send_file + print $self $buf; + } + close($file) if $opened; +- $cnt; ++ ++ # Return a "true zero" for empty-but-successful copies so callers ++ # using `send_file or die` can distinguish open failure (undef) ++ # from a successful zero-byte transfer. ++ $cnt || '0E0'; + } + + +@@ -917,6 +920,28 @@ Copy the file to the client. The file can be a string (which + will be interpreted as a filename) or a reference to an C + or glob. + ++Returns the number of bytes copied on success, or C if the ++filename form failed to open. An empty file returns the string ++C<'0E0'> (zero numerically, true in boolean context) so that callers ++using C<< send_file or die >> can distinguish open failure from a ++successful zero-byte transfer. ++ ++The filename form uses Perl's 3-argument C with an explicit C<< ++< >> mode, so the path is no longer interpreted as a 2-argument ++C shell-magic shape such as C<< | cmd >>, C<< cmd | >>, or ++C<< > path >>. See ++L for ++the prior 2-argument C behaviour this replaces. ++ ++Note that this fix only neutralises 2-argument C shell-magic. ++Callers remain responsible for validating attacker-influenced paths: ++C will still happily open symlinks, character/block devices ++(e.g. C, C), named pipes (which may block the ++worker), and files outside an intended document root. If C<$filename> ++can be derived from request input, validate it (canonicalise, reject ++C<..> segments, require C<-f _> and a vetted prefix) before passing it ++in. ++ + =item $c->daemon + + Return a reference to the corresponding C object. +-- +2.52.0 + diff --git a/perl-HTTP-Daemon.spec b/perl-HTTP-Daemon.spec index 7a7ccd5..93fa9e5 100644 --- a/perl-HTTP-Daemon.spec +++ b/perl-HTTP-Daemon.spec @@ -1,6 +1,6 @@ Name: perl-HTTP-Daemon Version: 6.01 -Release: 23%{?dist} +Release: 24%{?dist} Summary: Simple HTTP server class License: GPL+ or Artistic URL: http://search.cpan.org/dist/HTTP-Daemon/ @@ -13,6 +13,8 @@ Patch0: HTTP-Daemon-6.01-Add-IPv6-support.patch Patch1: HTTP-Daemon-6.01-Handle-undef-and-empty-LocalAddr.patch # Fix formatting specific non-local addresses, bug #1578026, CPAN RT#125242 Patch2: HTTP-Daemon-6.01-Resolve-specific-socket-addresses-correctly.patch +# https://github.com/libwww-perl/HTTP-Daemon/commit/945d35141d94490f749640bd4390acd6a2193995 +Patch3: HTTP-Daemon-6.01-CVE-2026-8450.patch BuildArch: noarch BuildRequires: make BuildRequires: perl-generators @@ -62,6 +64,7 @@ IO::Socket::IP, so you can perform socket operations directly on it too. %patch0 -p1 %patch1 -p1 %patch2 -p1 +%patch3 -p1 %build perl Makefile.PL INSTALLDIRS=vendor NO_PACKLIST=1 @@ -80,6 +83,10 @@ make test %{_mandir}/man3/* %changelog +* Wed Jun 17 2026 RHEL Packaging Agent - 6.01-24 +- Fix CVE-2026-8450: send_file() shell-magic injection via 2-arg open() +- Resolves: RHEL-184825 + * Wed May 23 2018 Petr Pisar - 6.01-23 - Fix formatting numerical non-local specific IPv6 addresses (bug #1578026)