SSL Certificate Analysis Open Port Detection Web Application Scanning DNS Security Audit HTTP Header Analysis Misconfiguration Detection Software Fingerprinting Subdomain Enumeration
SSL Certificate Analysis Open Port Detection Web Application Scanning DNS Security Audit HTTP Header Analysis Misconfiguration Detection Software Fingerprinting Subdomain Enumeration

All Entries

Category Injection
Typical Severity Critical
OWASP A03:2021 – Injection
CWE CWE-78 – Improper Neutralization of Special Elements used in an OS Command
Also known as Shell Injection, Command Injection, Remote Command Execution (RCE)
Affected systems Web applications, APIs, and back-end services that invoke OS shell functions (e.g., system(), exec(), popen(), subprocess) with user-controlled input
CVSS v3.1 Base Score (typical) 9.8 (Critical) – unauthenticated network-exploitable variants

Overview

OS Command Injection is a vulnerability in which an application passes unsanitised, attacker-controlled data to a system shell interpreter. The interpreter executes the injected tokens as discrete OS commands with the privileges of the application process. It is consistently ranked among the most dangerous vulnerability classes because a single successful exploit can yield full host compromise without requiring any further vulnerability chaining.

The weakness is catalogued as CWE-78 and is a member of the broader Injection category (OWASP A03:2021). It differs from Code Injection (CWE-94) in that the injected payload targets the OS shell rather than an application-level interpreter such as a scripting engine.

How it works

Vulnerable applications typically construct OS command strings by concatenating static command fragments with user-supplied values. Shell metacharacters in that input are interpreted by the shell, allowing command separation and chaining. Common attack patterns include:

  • Semicolon separator (;) – terminates the intended command and begins a new one: ping 127.0.0.1; id
  • Pipe operator (|) – pipes the output of the first command into the injected command: input | cat /etc/passwd
  • Logical AND / OR (&&, ||) – executes subsequent commands conditionally: dir && whoami
  • Backtick / dollar-parenthesis substitution (`cmd`, $(cmd)) – embeds command output inline: echo $(id)
  • Newline injection (%0a) – bypasses filters that block visible metacharacters.
  • Out-of-band (blind) injection – where the command output is not reflected in the HTTP response; exfiltration occurs via DNS lookups or HTTP callbacks.

Vulnerable code patterns exist across many languages and runtimes:

  • PHP: exec(), shell_exec(), passthru(), system(), backtick operator
  • Python: os.system(), subprocess.call(shell=True), os.popen()
  • Java: Runtime.exec() when the argument is constructed from user input as a shell string
  • Node.js: child_process.exec()
  • Ruby: system(), backtick operator, IO.popen()

The vulnerability is exploitable even when the application does not display command output (blind injection). Time-based probing (e.g., injecting sleep 5 or ping -n 5 127.0.0.1) can confirm exploitability without visible output.

Business impact

A successful OS Command Injection exploit grants the attacker the same OS-level privileges as the compromised application process. Consequences include:

  • Complete host compromise – arbitrary file read/write, process execution, and lateral movement across internal networks.
  • Data exfiltration – access to database credentials, private keys, environment variables, and sensitive files (/etc/shadow, application config files).
  • Persistence – installation of backdoors, web shells, or cron jobs that survive application restarts.
  • Service disruption – deliberate destruction or encryption of data, process termination, or network disruption.
  • Compliance and legal exposure – breach of GDPR, PCI DSS, HIPAA, and similar frameworks, with accompanying notification obligations and potential fines.
  • Reputational damage – public disclosure of a breach resulting from a well-known, preventable vulnerability class is frequently damaging to customer trust.

How to fix it

  1. Avoid shell invocation entirely. The most effective defence is to replace shell-dispatching functions with API-level equivalents that accept argument arrays and never invoke a shell. For example, use subprocess.run(["ping", host], shell=False) in Python instead of os.system("ping " + host). Argument-array forms prevent shell metacharacter interpretation because arguments are passed directly to the OS without shell parsing.
  2. Validate and allowlist input rigorously. If OS command invocation cannot be avoided, restrict user-supplied values to a strict allowlist of known-safe characters (e.g., alphanumeric only). Reject or abort on any input that does not match. Blocklisting metacharacters alone is insufficient and easily bypassed.
  3. Escape shell arguments correctly. When an allowlist is impractical, use language-provided escaping functions: shlex.quote() in Python, escapeshellarg() in PHP. Never write a custom escaping routine.
  4. Apply least-privilege principles. Run the application process under a dedicated OS user with the minimum permissions required. Use filesystem namespaces, containers, or jails to limit the blast radius of any successful injection.
  5. Disable unnecessary shell features. Where possible, disable or restrict the use of shell interpreters in the application runtime environment (e.g., disable PHP functions via disable_functions in php.ini).
  6. Implement security-focused code review and SAST. Include static analysis rules targeting shell-invocation sinks with tainted data sources in CI/CD pipelines.
  7. Deploy runtime protection. Web Application Firewalls (WAFs) and Runtime Application Self-Protection (RASP) agents can detect and block common injection patterns, but should be treated as defence-in-depth measures, not primary mitigations.
  8. Conduct regular penetration testing. Manual testing and automated scanning—Sensagraph detects OS Command Injection across web-accessible endpoints—should be part of a continuous security programme.

References

Frequently asked questions

OS Command Injection (CWE-78) targets the operating system's shell interpreter, allowing arbitrary OS commands to be run. Code Injection (CWE-94) targets an application-level interpreter (e.g., PHP eval, Python exec). Both are severe, but OS Command Injection typically yields more direct host-level access.

Yes. Some libraries and frameworks internally delegate to shell invocations. Additionally, certain language constructs (e.g., PHP backtick operator, Ruby system()) may not appear to be shell calls in a code review but are equivalent. Thorough SAST and dependency audits are necessary.

Blind OS Command Injection occurs when the application executes the injected command but does not return any output in the HTTP response. Attackers confirm and exploit it using time-delay payloads (e.g., `sleep 10`), out-of-band DNS callbacks, or writing output to a web-accessible file.

No. WAFs can block many known injection patterns but are bypassable using encoding, obfuscation, or novel payloads. The primary remediation is fixing the vulnerable code by avoiding shell invocation or enforcing strict allowlist validation. WAFs are a defence-in-depth layer, not a substitute for secure coding.

Network-exploitable, unauthenticated OS Command Injection vulnerabilities commonly receive CVSS v3.1 base scores of 9.8 (Critical), reflecting high impact on confidentiality, integrity, and availability with no privileges or user interaction required.