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.
| Attribute | Value |
|---|---|
| CVE ID | CVE-2026-8450 |
| Severity | Critical |
| CVSS v3 Score | 9.1 |
| CWE | CWE-78 — OS Command Injection |
| Vendor | Perl / CPAN |
| Product | HTTP::Daemon |
| Affected Versions | < 6.17 |
| Fixed Version | 6.17 |
| Published | May 27, 2026 |
| Source | NVD |
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 magicThe 2-argument form interprets magic prefixes in the filename string:
| Magic Prefix | Effect |
|---|---|
| cmd | Opens a pipe — executes cmd as a subprocess |
cmd | | Opens a pipe reading from cmd |
> path | Opens path for writing (overwrite) |
>> path | Opens path for appending |
< path | Normal 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
- 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. - 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.
- Arbitrary file write: Using
> /etc/cron.d/backdooras 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 manipulationAffected Versions
| Package | Affected | Fixed |
|---|---|---|
| HTTP::Daemon (CPAN) | < 6.17 | 6.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
-
Upgrade HTTP::Daemon to version 6.17 or later via CPAN:
cpan install HTTP::Daemon # or cpanm HTTP::Daemon -
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. -
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); -
Run Perl applications under a least-privilege user to limit the blast radius of any command injection.
-
Enable application-level input validation that rejects filenames containing shell metacharacters, even as a defense-in-depth measure beyond the patch.