Safeguard
Vulnerability Analysis

What is Command Injection

Command injection lets attackers run OS commands through unsanitized input. Learn how it works, real CVEs like Shellshock and PAN-OS, and how to prevent it.

Bob
Application Security Engineer
7 min read

Command injection happens when an application passes untrusted input into a system shell without sanitizing it first, letting an attacker append their own OS commands to the ones the developer intended to run. The flaw is tracked under CWE-78 and has powered some of the most damaging breaches of the last decade, from 2014's Shellshock (CVE-2014-6271, CVSS 10.0) to Palo Alto Networks' PAN-OS GlobalProtect zero-day in April 2024 (CVE-2024-3400, CVSS 10.0), which was actively exploited before a patch existed. Unlike SQL injection, which corrupts a database query, command injection hands an attacker a shell on the host itself — meaning file access, lateral movement, and full server takeover are all one crafted string away. This glossary entry breaks down how the vulnerability works, why it keeps recurring in 2024 and 2025, and what security teams need in place to catch it before attackers do.

What Is Command Injection?

Command injection is a vulnerability class where an application concatenates user-controlled input into a string that gets executed by the operating system shell, allowing an attacker to inject additional commands. It's cataloged by MITRE as CWE-78 ("Improper Neutralization of Special Elements used in an OS Command") and sits alongside CWE-77 (generic command injection) and CWE-88 (argument injection) in the broader family. The root cause is almost always the same: a call to a function like system(), exec(), popen(), or a shell-out library method, fed a string built from request parameters, filenames, or headers without validation. If an attacker can insert shell metacharacters — ;, &&, |, backticks, or $() — into that string, the shell will happily interpret them as command separators and run whatever follows with the same privileges as the vulnerable process.

How Does an Attacker Actually Exploit It?

An attacker exploits command injection by finding an input field that reaches a shell call, then appending metacharacters to chain a second command onto the legitimate one. A classic textbook example is a network diagnostic tool that runs ping against a user-supplied hostname: os.system("ping -c 4 " + hostname). A legitimate request might submit hostname=8.8.8.8, but an attacker submits hostname=8.8.8.8; cat /etc/passwd, and the shell executes both commands in sequence. In the real 2023 Zyxel firewall case (CVE-2023-28771, CVSS 9.8), attackers sent a single crafted UDP packet to port 500 that triggered unauthenticated OS command execution on the device — no login, no multi-step chain, just one packet. Within weeks it was folded into a Mirai-variant botnet used for DDoS attacks, according to Shadowserver Foundation scanning data published in mid-2023. That's the pattern across most command injection exploitation: find the shell-out, inject the metacharacter, execute with the process's existing privileges (frequently root on network appliances).

What's the Difference Between Command Injection and SQL Injection?

The difference is what gets interpreted: SQL injection corrupts a database query, while command injection corrupts an operating system command, and the second one is typically far more severe. A successful SQL injection usually gives an attacker read/write access to a database — serious, but bounded by what the database driver can do. A successful command injection gives an attacker a shell on the underlying host, which means reading arbitrary files, writing new files (including web shells or cron jobs), pivoting to other hosts on the network, and killing or modifying running processes. Both are injection flaws that stem from mixing untrusted data with executable syntax, and both are preventable with the same core discipline — never build executable strings by concatenating user input, use parameterized APIs instead — but a command injection finding should generally be triaged and patched faster because the blast radius is the entire host, not just a data store.

Which Real Breaches Were Caused by Command Injection?

Real breaches caused by command injection span two decades and every layer of the stack, from web frameworks to network appliances. Shellshock (CVE-2014-6271), disclosed in September 2014, exploited a flaw in how Bash parsed environment variables, letting attackers inject commands through anything that set an env var from user input — CGI scripts, DHCP clients, OpenSSH ForceCommand setups — and it was mass-exploited within 24 hours of disclosure. In April 2021, GitLab's ExifTool dependency shipped a DjVu file parsing bug (CVE-2021-22205, CVSS 9.8) that let an attacker upload a crafted image to trigger unauthenticated remote command execution on GitLab servers; despite a patch being available since April 2021, unpatched instances were still being actively exploited by botnets as late as 2022 per reporting from GreyNoise. Most recently, CVE-2024-3400 in Palo Alto Networks' PAN-OS GlobalProtect gateway combined an arbitrary file-creation bug with command injection to give unauthenticated attackers root shells on firewalls; Volexity and Palo Alto's own Unit 42 confirmed nation-state exploitation in the wild before the April 12, 2024 patch shipped, and CISA added it to the Known Exploited Vulnerabilities catalog the same week.

How Common Is Command Injection in Today's Software?

Command injection remains common enough that CWE-78 has held a top-5 spot on MITRE's CWE Top 25 Most Dangerous Software Weaknesses in recent years, ranking above longtime headline vulnerabilities like path traversal and cross-site request forgery. It's especially concentrated in three places: network and security appliances (firewalls, VPN gateways, routers) where vendors frequently shell out to system binaries like ping, traceroute, or iptables for admin features; CI/CD and DevOps tooling that wraps git, tar, or container runtimes; and image/document processing pipelines that call out to tools like ImageMagick, FFmpeg, or ExifTool. Because these tools are so often pulled in as third-party dependencies rather than written in-house, a command injection bug in one library — as with GitLab's ExifTool dependency — can silently propagate into every downstream application that bundles it, which is exactly why dependency-level visibility matters as much as first-party code review.

How Can Teams Prevent Command Injection?

Teams prevent command injection primarily by never letting user input reach a shell interpreter in the first place. Concretely, that means: use language APIs that execute a binary with an argument array (Python's subprocess.run(["ping", "-c", "4", hostname]), Node's execFile instead of exec) rather than building a single shell string; if a shell is unavoidable, allowlist input against a strict pattern (e.g., valid hostname characters only) instead of trying to blocklist dangerous ones; and run any process that must shell out with the minimum OS privileges available, so a successful injection doesn't hand over root. On the dependency side, teams should track which third-party libraries call system(), exec(), or similar functions internally — a library update can introduce a shell-out that wasn't there in the previous version — and prioritize patching appliance and CI/CD software fast, since those are the categories attackers have targeted repeatedly since Shellshock.

How Safeguard Helps

Safeguard helps teams find and fix command injection risk before attackers do by combining SBOM generation and ingest with reachability analysis, so instead of flagging every dependency that contains a CWE-78 pattern, it identifies which vulnerable functions are actually reachable from your application's call paths. Griffin AI, Safeguard's detection engine, correlates that reachability data with real exploitation signals — like the in-the-wild activity seen with CVE-2024-3400 and CVE-2023-28771 — to separate urgent findings from theoretical ones and cut through alert fatigue. When a fix is available, Safeguard can open an auto-fix pull request that bumps the affected dependency or patches the vulnerable call, so remediation doesn't stall in a backlog. For appliances, CI/CD tools, and image-processing pipelines — the categories most frequently hit by command injection in the wild — this means security teams get a prioritized, reachability-verified list instead of a raw CVE feed.

Never miss an update

Weekly insights on software supply chain security, delivered to your inbox.