VYPR
Unrated severityNVD Advisory· Published May 27, 2026· Updated May 27, 2026

CVE-2026-8450

CVE-2026-8450

Description

HTTP::Daemon versions before 6.17 for Perl allow OS command injection via send_file().

send_file() opens its string argument with Perl's 2-arg open(). The 2-arg form interprets magic prefixes: '| cmd' and 'cmd |' open a pipe to a subprocess, '> path' and '>> path' open the path for write or append.

Untrusted input passed to send_file() can run OS commands at the daemon process UID. The read-pipe form ('cmd |') also leaks subprocess stdout into the HTTP response body. The write-mode forms can create or truncate files at attacker chosen paths.

AI Insight

LLM-synthesized narrative grounded in this CVE's description and references.

HTTP::Daemon before 6.17 allows OS command injection or arbitrary file write when send_file() is called with attacker-influenced input due to use of Perl's 2-arg open().

Vulnerability

The send_file() method in HTTP::Daemon::ClientConn before version 6.17 uses Perl's 2-argument open(FILE, $file) call, which interprets shell-magic prefixes in the path argument [1][2]. When an attacker-controlled string is passed to send_file(), the characters |, >, >>, +<, &, or leading whitespace can trigger pipe commands or file redirections instead of a normal file open. The vulnerability affects all versions prior to 6.17 [3]. The fix switches to 3-arg open(my $fh, '<', $file), ensuring the path is treated as a literal filename.

Exploitation

An attacker must be able to influence the string argument passed to send_file(), for example by providing a filename via a query parameter to a download endpoint [1][2]. No authentication or special network position is required if the endpoint is publicly accessible. By crafting input such as | command (write pipe), command | (read pipe), > /path/to/write (truncate-and-write), or >> /path/to/append, the attacker achieves command execution or arbitrary file operations at the daemon's UID [2].

Impact

Successful exploitation yields OS command injection as the daemon process user, enabling full system compromise within that user's scope [1][2]. The read-pipe form (command |) also leaks the subprocess's stdout into the HTTP response body, exfiltrating output. Write-mode forms (>, >>) allow creating or overwriting arbitrary files, potentially leading to privilege escalation or denial of service.

Mitigation

Upgrade to HTTP::Daemon version 6.17 (released 2026-05-19) or later [3]. The fix replaces the dangerous 2-arg open with a 3-arg open that does not interpret shell-magic. No workaround is available for users who cannot upgrade; administrators must ensure no attacker-influenced input reaches send_file() by applying strict input validation and sanitisation [2].

AI Insight generated on May 27, 2026. Synthesized from this CVE's description and the cited reference URLs; citations are validated against the source bundle.

Affected products

2

Patches

2
945d35141d94

Fix CVE-2026-8450: send_file() honoured 2-arg open() shell-magic

https://github.com/libwww-perl/http-daemonOlaf AldersMay 14, 2026via body-scan
2 files changed · +42 5
  • Changes+12 0 modified
    @@ -1,6 +1,18 @@
     Revision history for HTTP-Daemon
     
     {{$NEXT}}
    +  - Fix CVE-2026-8450 (affects 6.15 and earlier): 2-arg open() in
    +    send_file() enabled RCE / arbitrary file write / response-body
    +    exfiltration when a string argument was derived from attacker-
    +    influenced input. send_file() now uses 3-arg open() with an
    +    explicit '<' read mode, so the path is always treated as a literal
    +    filename and 2-arg open() shell-magic shapes ('| cmd', 'cmd |',
    +    '> path', etc.) are no longer interpreted. send_file() now also
    +    returns '0E0' (true zero) on a successful zero-byte transfer so
    +    callers can distinguish empty file from open failure (undef). See
    +    https://www.cve.org/CVERecord?id=CVE-2026-8450 for the advisory.
    +    Reported and patched by Stig Palmquist (stigtsp). (Stig Palmquist,
    +    Olaf Alders)
       - Bump LWP::UserAgent to 6.37 in TestSuggests (GH#65) (Olaf Alders)
     
     6.15      2023-02-22 22:02:46Z
    
  • lib/HTTP/Daemon.pm+30 5 modified
    @@ -598,11 +598,10 @@ sub send_dir {
     sub send_file {
         my ($self, $file) = @_;
         my $opened = 0;
    -    local (*FILE);
         if (!ref($file)) {
    -        open(FILE, $file) || return undef;
    -        binmode(FILE);
    -        $file = \*FILE;
    +        open(my $fh, '<', $file) || return undef;
    +        binmode($fh)             || do { close($fh); return undef };
    +        $file = $fh;
             $opened++;
         }
         my $cnt = 0;
    @@ -614,7 +613,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';
     }
     
     sub daemon {
    @@ -896,6 +899,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<IO::Handle>
     or glob.
     
    +Returns the number of bytes copied on success, or C<undef> 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<open> with an explicit C<<
    +< >> mode, so the path is no longer interpreted as a 2-argument
    +C<open> shell-magic shape such as C<< | cmd >>, C<< cmd | >>, or
    +C<< > path >>.  See
    +L<CVE-2026-8450|https://www.cve.org/CVERecord?id=CVE-2026-8450> for
    +the prior 2-argument C<open> behaviour this replaces.
    +
    +Note that this fix only neutralises 2-argument C<open> shell-magic.
    +Callers remain responsible for validating attacker-influenced paths:
    +C<send_file> will still happily open symlinks, character/block devices
    +(e.g. C</dev/zero>, C</dev/stdin>), 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<HTTP::Daemon> object.
    
7aa2827eefee

t/send-file-magic-open: drop redundant pipe spellings

https://github.com/libwww-perl/http-daemonOlaf AldersMay 16, 2026via body-scan
1 file changed · +6 6
  • t/send-file-magic-open.t+6 6 modified
    @@ -45,13 +45,13 @@ my $writer
         = qq{$^X -e 'open my \$f, q{>}, \$ENV{HTTPD_MAGIC_MARKER} or die; close \$f'};
     
     my @magic_shapes = (
    -    {name => 'write-pipe', shape => sub {"| $writer"}},
    -    {name => 'read-pipe',  shape => sub {"$writer |"}},
     
    -    # 2-arg open() strips leading whitespace before checking for magic
    -    # prefixes, so " | cmd" (note the leading space) is also a pipe.
    -    {name => 'leading-ws-pipe', shape => sub {" | $writer"}},
    -    {name => 'write-redirect',  shape => sub { my ($m) = @_; "> $m" }},
    +    # One pipe shape stands for the whole command-execution family
    +    # (| cmd, cmd |, ...). The leading-space spelling is the one kept:
    +    # 2-arg open() strips leading whitespace before testing for a magic
    +    # prefix, so " | cmd" also exercises that quirk.
    +    {name => 'pipe',           shape => sub {" | $writer"}},
    +    {name => 'write-redirect', shape => sub { my ($m) = @_; "> $m" }},
     );
     
     for my $case (@magic_shapes) {
    

Vulnerability mechanics

Root cause

"send_file() used Perl's two-argument open(), which interprets shell-magic prefixes in the filename argument as pipe commands or file redirections instead of literal filenames."

Attack vector

An attacker supplies a string to `send_file()` that begins with a shell-magic prefix such as `| cmd`, `cmd |`, `> path`, or `>> path` [ref_id=1]. Because the function used Perl's two-argument `open()`, these prefixes are interpreted as pipe-to-command, pipe-from-command, or write/append redirections rather than literal filenames [patch_id=2623896]. The read-pipe form (`cmd |`) also leaks the subprocess's stdout into the HTTP response body. Any HTTP::Daemon-based application that passes attacker-influenced bytes to `send_file()` — for example, a download endpoint that derives the filename from a query parameter — grants OS command execution and/or arbitrary file write at the daemon's process UID [ref_id=1].

Affected code

The vulnerability is in `HTTP::Daemon::ClientConn::send_file()` in `lib/HTTP/Daemon.pm` [patch_id=2623896]. The function used the two-argument form `open(FILE, $file)`, which interprets shell-magic prefixes in the string argument [ref_id=1]. The patch replaces this with the three-argument form `open(my $fh, '

What the fix does

The patch switches from two-argument `open(FILE, $file)` to three-argument `open(my $fh, '

Preconditions

  • inputThe application must pass attacker-influenced input as the string argument to send_file(), e.g. deriving a filename from a query parameter.
  • networkNo authentication or special network position is required beyond the ability to send HTTP requests to the daemon.

Generated on May 27, 2026. Inputs: CWE entries + fix-commit diffs from this CVE's patches. Citations validated against bundle.

References

4

News mentions

0

No linked articles in our index yet.