CWE-78 is OS command injection. The product builds all or part of an operating system command from externally influenced input, and fails to neutralize special elements that could change the command before it reaches the OS.
It hits web applications, network devices, admin tools and anything else that shells out. It is especially serious in web apps, because MITRE notes the weakness can turn a situation where the attacker has no direct access to the operating system into one where they effectively do.
How it happens
MITRE describes two subtypes.
- The application intends to run a single, fixed program under its own control, and use outside input as arguments. The example is
system("nslookup [HOSTNAME]"). The attacker cannot stop nslookup from running, but if command separators are not removed from the host name, they can add further commands. - The application accepts an input that it uses to select which program to run, so the attacker can choose a different command altogether.
Here is the first subtype in Python:
import os
# Vulnerable: input goes into a shell string
host = request.args["host"]
os.system("nslookup " + host)
# host = "example.com; cat /etc/passwd" runs a second command
And the same shape in Node:
const { exec } = require("child_process");
// Vulnerable: exec runs its argument through a shell
exec("nslookup " + req.query.host, callback);
The fix is to stop using a shell string and pass arguments separately:
import subprocess, re
host = request.args["host"]
if not re.fullmatch(r"[A-Za-z0-9.-]{1,253}", host):
abort(400)
subprocess.run(["nslookup", host], check=True, shell=False)
const { execFile } = require("child_process");
execFile("nslookup", [req.query.host], callback);
With an argument array there is no shell to interpret a semicolon. The allowlist check in the Python version adds a second layer. One caution from MITRE's argument injection entry (CWE-88): a value that starts with a dash can still be read as an option by the program you launch, so validate the shape of the value too.
The observed examples in the record include:
- CVE-2024-53899: a virtual environment builder that does not correctly quote "magic" template strings, allowing OS command injection using a directory whose name contains shell metacharacters.
- CVE-2025-44844: file upload functionality in a wireless access point that allows OS command injection via shell metacharacters in the file name of a Content-Disposition header.
- CVE-2024-41316: a Lua application in a network device that allows OS command injection into os.execute().
- CVE-2024-6091: a chain in an AI agent platform that does not restrict pathnames containing internal "/./" sequences, leading to an incomplete denylist that does not prevent OS command injection.
Gold pages: CVE-2024-53899, CVE-2025-44844, CVE-2024-41316 and CVE-2024-6091.
Notice how many inputs count as "outside": a directory name, an uploaded file name, a header value. Anything an attacker can influence is a candidate.
What an attacker gains
MITRE says attackers could execute unauthorized operating system commands. The listed impacts are broad: confidentiality, integrity, availability and non-repudiation, including reading and modifying files, reading and modifying application data, crashing or restarting the service, and hiding activities.
The damage grows when the compromised process does not follow least privilege, because attacker-controlled commands may run with special system privileges.
How to find it
MITRE lists several methods.
- Automated static analysis. Many tools use data flow or constraint techniques to limit false positives. They may not recognize when proper validation is in place, and may miss custom or indirect flows.
- Automated dynamic analysis. Fuzzing, robustness testing and fault injection with many diverse inputs. The product may slow down, but it should not become unstable, crash or generate incorrect results.
- Manual static analysis. The weakness does not usually appear often in one package, so a careful white box review of every operation that launches a process can give enough coverage.
- Bytecode and binary analysis. MITRE cites a source that rates bytecode and binary weakness analysis, with a disassembler and source weakness analysis, as cost effective.
Click through it at your own pace, or open it full screen.
How to fix it
In order of strength, following the record:
- Do not run a process at all. Use library calls to recreate the function where possible.
- Use structured calls. Replace functions that run a command through a shell with a single string, with ones that take individual arguments. In C, prefer execl or execve over system. Windows CreateProcess accepts only one command at a time. In Perl, system with an array quotes each argument.
- Encode and quote correctly. MITRE states that proper output encoding, escaping and quoting is the most effective solution, while input validation is defense in depth. If you must build a string, escape or filter everything outside a strict allowlist, then quote.
- Validate input with an allowlist. Limit characters by the expected value of each parameter. Free-form text, such as an email subject that may legitimately contain ";" or ">", cannot be fully validated, so encoding matters.
- Pass arguments by file or stdin if the program supports it, instead of the command line.
- Limit the damage. Run in a jail or sandbox such as chroot, AppArmor or SELinux (effectiveness is limited, and it may reduce only the scope of an attack). Run with least privilege. MITRE also suggests an environment that does taint tracking and blocks tainted command execution, such as Perl's "-T" switch.
- Repeat client checks on the server. An attacker can edit anything done in the browser.
- Keep error messages minimal so attackers cannot tune their attack from details.
Quick check
Why is exec with a string riskier than execFile with an array?
The string version goes through a shell that interprets separators and metacharacters. The array version passes each argument directly to the program.
Does input validation alone stop command injection?
Not always. MITRE says encoding and quoting is the most effective control, and validation is defense in depth, especially when free-form text must be allowed.