SECURITYCRITICALCVE-2026-8450

CVE-2026-8450: HTTP::Daemon Perl OS Command Injection via send_file()

OS command injection (CVSS 9.1) in Perl's HTTP::Daemon lets attackers run arbitrary commands via magic prefix abuse in send_file's two-arg open().

Dylan H.

Security Team

May 27, 2026
3 min read
CVE-2026-8450: HTTP::Daemon Perl OS Command Injection via send_file()

Critical severity

Rated critical. Prioritise patching — see the remediation guidance below.

Affected Products

  • HTTP::Daemon < 6.17 (Perl)

Executive Summary

CVE-2026-8450 is a critical OS command injection vulnerability (CVSS 9.1) affecting HTTP::Daemon versions before 6.17 for Perl. The vulnerability exists in the send_file() method, which opens its string argument using Perl's dangerous 2-argument form of open(). This form interprets magic prefixes such as | cmd (pipe to subprocess) and cmd |, > path, and >> path, allowing an attacker who can control the filename argument to execute arbitrary OS commands or write to arbitrary files.


AttributeValue
CVE IDCVE-2026-8450
SeverityCritical
CVSS v3 Score9.1
CWECWE-78 — OS Command Injection
VendorPerl / CPAN
ProductHTTP::Daemon
Affected Versions< 6.17
Fixed Version6.17
PublishedMay 27, 2026
SourceNVD

Technical Details

The Perl 2-Argument open() Problem

Perl's open() function exists in two forms:

# 3-argument form — safe, no magic
open(my $fh, '<', $filename);
 
# 2-argument form — DANGEROUS, interprets magic prefixes
open(my $fh, $filename);  # $filename is interpreted for magic

The 2-argument form interprets magic prefixes in the filename string:

Magic PrefixEffect
| cmdOpens a pipe — executes cmd as a subprocess
cmd |Opens a pipe reading from cmd
> pathOpens path for writing (overwrite)
>> pathOpens path for appending
< pathNormal file read

The Vulnerable Code Pattern

HTTP::Daemon's send_file() method passes the caller-controlled filename string directly to the 2-argument open():

sub send_file {
    my ($self, $filename) = @_;
    open(my $fh, $filename) or return;  # 2-arg open — VULNERABLE
    # ... reads and sends file contents over HTTP ...
}

If an attacker can influence the $filename argument (e.g., through a web application layer that calls send_file() with user input), they can pass a string like:

| id; whoami; cat /etc/passwd |

Perl will interpret this as a pipe command, executing the embedded shell commands with the privileges of the Perl process.

Exploitation Scenarios

  1. Web application calling send_file() with user input: Any Perl web application that passes user-controlled path values to send_file() without sanitization is exploitable.
  2. File server using HTTP::Daemon directly: If the filename originates from a URL path or query parameter without strict validation, the magic prefix bypass applies.
  3. Arbitrary file write: Using > /etc/cron.d/backdoor as the filename argument opens the file for writing, enabling persistent backdoor installation.

Attack Chain

1. Attacker sends HTTP request with malicious filename argument
2. Application passes filename to HTTP::Daemon's send_file()
3. send_file() calls 2-arg open($filename)
4. Perl interprets magic prefix: "| cmd" spawns subprocess
5. Arbitrary OS commands execute with web server process privileges
6. Reverse shell, data exfiltration, or file manipulation

Affected Versions

PackageAffectedFixed
HTTP::Daemon (CPAN)< 6.176.17+

Indicators of Compromise

Application Log Anomalies

  • Requests containing |, >, >> characters in filename parameters served by HTTP::Daemon endpoints
  • Unexpected subprocess spawning from Perl web processes (visible in process trees)
  • Unusual outbound connections from Perl application servers

System-Level Indicators

  • Unexpected files created in sensitive directories (/etc/cron.d/, /var/spool/cron/, web roots)
  • New or modified cron jobs associated with the Perl web application service account
  • Shell processes (sh, bash) spawned as children of Perl interpreter processes

Remediation

  1. Upgrade HTTP::Daemon to version 6.17 or later via CPAN:

    cpan install HTTP::Daemon
    # or
    cpanm HTTP::Daemon
  2. Audit all calls to send_file() in your codebase. If user-controlled input reaches the filename argument, sanitize it to reject magic-prefix characters (|, >, <) before the fix is applied.

  3. Switch to the 3-argument open() form if you maintain a fork or wrapper of HTTP::Daemon:

    # Replace:
    open(my $fh, $filename);
    # With:
    open(my $fh, '<', $filename);
  4. Run Perl applications under a least-privilege user to limit the blast radius of any command injection.

  5. Enable application-level input validation that rejects filenames containing shell metacharacters, even as a defense-in-depth measure beyond the patch.


References